从字节数组创建一个字符串不会返回相同的长度

时间:2015-11-27 17:57:56

标签: java arrays string encoding

我有这个问题,我在一个方法中收到一个String,在数据库中必须限制为200(Varchar),虽然String的长度小于200,但显然字节长度超过200,但是某些字符所以我试着这样做:

获取字符串的字节长度

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

然后如果nameBytes.length> 200我尝试使用原始nameBytes的子数组创建一个新的String,如下所示:

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

我确信Arrays.copyOfRange(nameBytes,0,200)返回一个长度为200的数组,但由于某种原因,当我创建新的String时,此修订名称为.getBytes(“UTF-8”)。length给了我201,所以我不知道为什么再添加一个字节。

我做错了什么?或者有一种方法可以确保创建一个与char数组长度相同的数组?

提前致谢。

1 个答案:

答案 0 :(得分: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的信息,请参阅Byte order mark
  • dixit Unicode Character Representations:char数据类型(因此Character对象封装的值)基于原始Unicode规范,该规范将字符定义为固定宽度的16位实体。

这里的问题是关于数据库中使用的字符集。如果它是UTF-8,那么当你达到200字节限制时,你必须逐个字符地检查。使用UTF-8,您无法在任意字节数上剪切字符串:它可以位于任何2字节字符的中间。结果是不可预测的。

相关问题