我有这个问题,我在一个方法中收到一个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数组长度相同的数组?
提前致谢。
答案 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
评论:
这里的问题是关于数据库中使用的字符集。如果它是UTF-8,那么当你达到200字节限制时,你必须逐个字符地检查。使用UTF-8,您无法在任意字节数上剪切字符串:它可以位于任何2字节字符的中间。结果是不可预测的。