Java 从字节数组创建字符串时返回的长度不同

Java 从字节数组创建字符串时返回的长度不同,java,arrays,string,encoding,Java,Arrays,String,Encoding,我有这个问题,我在一个方法中接收到一个字符串,该方法在数据库中必须限制为200(Varchar),带有某些字符,尽管字符串的长度小于200,显然字节长度大于200,所以我尝试这样做: 获取字符串的字节长度 byte[] nameBytes = name.getBytes("UTF-8"); 然后,如果nameBytes.length>200,我将尝试创建一个新字符串,其中包含原始nameBytes的子数组,如下所示: name = new String(Arrays.copyOfRange(n

我有这个问题,我在一个方法中接收到一个字符串,该方法在数据库中必须限制为200(Varchar),带有某些字符,尽管字符串的长度小于200,显然字节长度大于200,所以我尝试这样做:

获取字符串的字节长度

byte[] nameBytes = name.getBytes("UTF-8");
然后,如果nameBytes.length>200,我将尝试创建一个新字符串,其中包含原始nameBytes的子数组,如下所示:

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

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

提前感谢。

先举几个例子:



        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表,请参见
  • dixit:char数据类型(以及Character对象封装的值)基于原始Unicode规范,该规范将字符定义为固定宽度的16位实体

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

字节不是字符。UTF-8以1-4字节存储信息。您的数据库限制字节数还是字符数?到底是哪个数据库管理系统?@SamM有办法知道字符数吗?我猜是一个字符串保存字符,对吗?@Thomas是DB2,我猜它是受字节限制的,但我不确定,因为例如使用String.length()我得到了我猜的字符数,在本例中少于150个,但getBytes函数显示的字符数超过201个,并且它正在标记错误。