我有一些代码可以从char数组转换为字节数组(不创建任何中间字符串,这是一个要求),最后我会得到一些额外的字节。以下是一些说明问题的测试代码:
String s = "TomJSawyer";
System.out.println("Original String length = " + s.length( ));
char[] caOrig = s.toCharArray( );
System.out.println("Original Char Array Length = " + caOrig.length);
byte[] ba1 = Charset.forName("UTF-8").encode(CharBuffer.wrap(caOrig)).array();
System.out.println("byte array converted from char array length = " + ba1.length);
byte[] ba2 = s.toString( ).getBytes("UTF-8");
System.out.println("byte array converted from String length = " + ba2.length);
这是在Winodows上的jdk160_24上运行的输出。
Original String length = 10
Original Char Array Length = 10
byte array converted from char array length = 11
byte array converted from String length = 10
使用Charset从char数组转换产生的额外字节为零值。随着输入字符串变长,附加到字节数组末尾的零字节数增加。我希望这与编码有关,但似乎我在两个地方都指定了UTF-8,所以我不知道为什么会这样。
如果有人能向我解释发生了什么或以其他方式指出了我正确的方向,我真的很感激。提前谢谢。
答案 0 :(得分:5)
documentation for CharsetEncoder.encode
说:
<强>返回:强> 新分配的字节缓冲区,包含编码操作的结果。缓冲区的位置将为零,其限制将跟随写入的最后一个字节。
您错误地认为ByteBuffer的整个后备阵列是有效数据。您应该只查看字节直到ByteBuffer的limit。事实上,CharsetEncoder.encode方法不保证返回的ByteBuffer甚至可以由数组支持,因此您根本不应该调用array()
。
阅读ByteBuffer的可靠方法是:
ByteBuffer buffer = Charset.forName("UTF-8").encode(CharBuffer.wrap(caOrig));
byte[] ba1 = new byte[buffer.limit()];
buffer.get(ba1);
答案 1 :(得分:0)
如果您不必使用char[]
,则可以使用StringBuffer
:
StringBuffer sb = "TomJSawyer";
String.valueOf(sb).getBytes();
答案 2 :(得分:0)
在许多情况下,字符数组大小与字节数组大小不同。当我在char数组中使用中文或日文字符时,它们不相同。我刚修复了我的应用程序中与此相关的错误。
以下是使用中文字符的测试代码段:
public static void main(String[] args) throws Exception {
char[] chars = new char[] { '中', '国' };
System.out.println("string content: " + new String(chars));
System.out.println("char array size: " + chars.length);
byte[] bytes = new String(chars).getBytes("UTF-8");
System.out.println("byte array size: " + bytes.length);
System.out.println("converted string content: " + new String(bytes, "UTF-8"));
}
以下是控制台的输出:
string content: 中国
char array size: 2
byte array size: 6
converted string content: 中国
不要再犯同样的错误了。