从字节数组创建字符串,长度不一致

3

我有一个问题,我在一个方法中接收到一个字符串,但是在数据库中这个字符串必须被限制为200个字符(Varchar),其中包含特定的字符,尽管该字符串的长度小于200,但是字节长度似乎超过了200,因此我尝试做如下处理:

获取字符串的字节长度

byte[] nameBytes = name.getBytes("UTF-8");

如果nameBytes的长度大于200,我会尝试使用原始nameBytes的子数组创建一个新的字符串,如下所示:

name = new String(Arrays.copyOfRange(nameBytes, 0, 200), "UTF-8");

我确定Arrays.copyOfRange(nameBytes, 0, 200)返回长度为200的数组,但是当我创建新的String时,revision name.getBytes("UTF-8").length给出201,所以我不知道为什么会增加一个字节。
我做错了什么吗?或者有没有一种方法可以确保创建与字符数组相同长度的数组?
提前致谢。

字节不是字符。UTF-8将信息存储在1-4个字节中。 - Sam McCreery
1
你的数据库限制字节数还是字符数?它是哪个DBMS? - Thomas
@SamM 有没有办法知道字符的数量?我猜字符串保存字符,对吗? - John B
@Thomas,我猜DB2是按字节限制的,但我不确定,因为例如使用string.length()函数可以得到字符数,而在这种情况下字符数少于150个,但getBytes函数显示超过201个并标记错误。 - John B
1个回答

1

首先是一些例子:



        String cs;
        String name = "façade";
        byte[] nameBytes;        

        System.out.println(String.format("String '%s': %d", name, name.length()));
        cs = "UTF-8";
        nameBytes = name.getBytes(Charset.forName(cs));
        System.out.println(String.format("%s: %d / %d", cs, nameBytes.length, new String(nameBytes, cs).length()));
        cs = "UTF-16";
        nameBytes = name.getBytes(Charset.forName(cs));
        System.out.println(String.format("%s: %d / %d", cs, nameBytes.length, new String(nameBytes, cs).length()));
        cs = "UTF-16BE";
        nameBytes = name.getBytes(Charset.forName(cs));
        System.out.println(String.format("%s: %d / %d", cs, nameBytes.length, new String(nameBytes, cs).length()));

带有输出:



    String 'façade': 6  ---> 6 characters with one outside ASCII range
    UTF-8: 7 / 6 ---> 'ç' requires 2 bytes, the others only one
    UTF-16: 14 / 6 ---> 2 x 6 bytes for code points + 2 bytes for BOM
    UTF-16BE: 12 / 6 ---> no need to embedded the BOM here => 2 x 6 bytes are enough

评论:

  • 始终指定字符集,即双向指定。
  • 关于BOM,请参见字节顺序标记
  • 引自Unicode字符表示:char数据类型(因此Character对象封装的值)基于最初的Unicode规范,该规范将字符定义为固定宽度的16位实体。

这里的问题是关于数据库中使用的字符集。如果是UTF-8,则在达到200个字节限制时需要逐个字符检查。使用UTF-8时,无法在任意字节数上截断字符串:它可能在任何两个字节字符的中间。结果是不可预测的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接