为什么Charset.encoder在转换此字符数组时会添加空值?

时间:2016-06-22 12:05:26

标签: java character-encoding

这个问题具体问为什么我从这个编码中得到空值,并且不是关于如何将字符串转换为字节数组的一般性问题。

我的实际用例涉及我的输入是一个字符数组,我想将其作为编码字节数组写入磁盘。

为什么当我尝试以这种方式对字符串进行编码时,结果会尾随空值?

String someInput = "///server///server///server///";

char[] chars = someInput.toCharArray();
Charset encoding = StandardCharsets.UTF_8;

CharBuffer buf = CharBuffer.wrap(chars);

for (byte b : encoding.newEncoder().encode(buf).array())
   System.out.println("-> " + new Character((char)b));

输出如下。请注意,在结果示例中,我已使用'�'替换了空值。 Unicode字符可提高可见性。

-> /
-> /
-> /
-> s
-> e
-> r
-> v
-> e
-> r
-> /
-> /
-> /
-> s
-> e
-> r
-> v
-> e
-> r
-> /
-> /
-> /
-> s
-> e
-> r
-> v
-> e
-> r
-> /
-> /
-> /
-> �
-> �
-> �

2 个答案:

答案 0 :(得分:1)

创建基础数组时,它不知道它应该有多大,并且一次增加多个字节/字符(一次添加一个字节效率非常低)

但是,一旦完成文本的转换,它就不会缩小数组以使其变小(或复制),因为这也会很昂贵。

简而言之,您不能假设底层缓冲区正好是它需要的大小,它可能更大。您应该将position()和limit()视为要使用的字节的边界。

答案 1 :(得分:1)

我同意@Peter的答案,他是对的,我只想添加一个与之相关的查找,我调试这段代码并发现在下面的for循环中: 在电话会议上:

 encoding.newEncoder().encode(buf).array()

我调试encode(buf)方法调用,发现在CharsetEncoder.java文件中,在encode()方法中,在开始实际编码之前,它计算缓冲区大小以通过下面的行分配编码字节:

 int n = (int)(in.remaining() * averageBytesPerChar());
  

此处 averageBytesPerChar()返回1.1,输入的大小(“ /// server /// server /// server /// ”)是30,这就是为什么总的大小   新分配的缓冲区,即n变为33。

这就是为什么在输出中你会看到3个额外的空格。希望它能帮助你更多地理解。