Java字符串转化为字节数组的问题

3

我正在尝试将一个ByteArray编码/解码成String,但输入和输出不匹配。我做错了什么吗?

System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(by));
String s = new String(by, Charsets.UTF_8);
System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(s.getBytes(Charsets.UTF_8)));

输出结果为:
130021000061f8f0001a
130021000061efbfbd

完整代码:

String[] arr = {"13", "00", "21", "00", "00", "61", "F8", "F0", "00", "1A"};        
byte[] by = new byte[arr.length];

for (int i = 0; i < arr.length; i++) {
    by[i] = (byte)(Integer.parseInt(arr[i],16) & 0xff); 
}

System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(by));

String s = new String(by, Charsets.UTF_8);
System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(s.getBytes(Charsets.UTF_8)));

你最初想要实现什么? - biziclop
@biziclop 我正在接收一个10字节的字符串,前3个字节代表number1,接下来的两个字节代表number2,下一个字节代表number3,剩余的4个字节代表number4。 - banjara
3个回答

5
问题在于f8f0001a不是有效的UTF-8字节序列。
首先,f8开头的字节表示5个字节的序列,而你只有4个字节。其次,f8后面只能跟着8x9xaxbx格式的字节。
因此,它被替换为一个unicode replacement character (U+FFFD),其在UTF-8中的字节序列为efbfbd
并且(正确地)没有保证将无效的字节序列转换成字符串再转回来会得到相同的字节序列。(请注意,即使是两个看起来相同的字符串,它们在Unicode中表示的字节也可能不同,参见Unicode equivalence。)
故事的寓意是:如果你想表示字节,请不要将它们转换为字符;如果你想表示文本,请不要使用字节数组。

3

2

当你从字节数组构建 String 时,这些字节会被解码。

由于代码中的字节不代表有效字符,所以最终组成 String 的字节与你传递的参数不同。

public String(byte[] bytes)

使用平台默认字符集解码指定的字节数组构造一个新的String。新String的长度取决于字符集,因此可能不等于字节数组的长度。

当给定的字节在默认字符集中无效时,此构造函数的行为是未指定的。如果需要对解码过程进行更多控制,则应使用CharsetDecoder类。


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