Java bug?为什么utf8编码中有额外的零字节?

Dim*_*ims 8 java utf-8 character-encoding

以下代码

public class CharsetProblem {
public static void main(String[] args) {
    //String str = "aaaaaaaaa";
    String str = "aaaaaaaaaa";
    Charset cs1 = Charset.forName("ASCII");
    Charset cs2 = Charset.forName("utf8");

    System.out.println(toHex(cs1.encode(str).array()));
    System.out.println(toHex(cs2.encode(str).array()));

}

public static String toHex(byte[] outputBytes) {

    StringBuilder builder = new StringBuilder();

    for(int i=0; i<outputBytes.length; ++i) {
        builder.append(String.format("%02x", outputBytes[i]));
    }

    return builder.toString();
}
}
Run Code Online (Sandbox Code Playgroud)

回报

61616161616161616161
6161616161616161616100
Run Code Online (Sandbox Code Playgroud)

即utf8编码返回多余的字节.如果我们采取较少的,那么我们将没有多余的字节.如果我们采取更多,因为我们可以获得越来越多的字节.

为什么?

怎么可以解决这个问题?

Gre*_*pff 7

您不能只获取支持数组并使用它.ByteBuffers具有容量,位置和限制.

System.out.println(cs1.encode(str).remaining());
System.out.println(cs2.encode(str).remaining());
Run Code Online (Sandbox Code Playgroud)

生产:

10
10
Run Code Online (Sandbox Code Playgroud)

试试这个:

public static void main(String[] args) {
  //String str = "aaaaaaaaa";
  String str = "aaaaaaaaaa";
  Charset cs1 = Charset.forName("ASCII");
  Charset cs2 = Charset.forName("utf8");

  System.out.println(toHex(cs1.encode(str)));
  System.out.println(toHex(cs2.encode(str)));
}

public static String toHex(ByteBuffer buff) {
  StringBuilder builder = new StringBuilder();
  while (buff.remaining() > 0) {
    builder.append(String.format("%02x", buff.get()));
  }
  return builder.toString();
}
Run Code Online (Sandbox Code Playgroud)

它产生了预期的:

61616161616161616161
61616161616161616161
Run Code Online (Sandbox Code Playgroud)


Ern*_*ill 6

你假设a的支持数组ByteBuffer恰好是保存内容的正确大小,但不一定如此.实际上,内容甚至不需要从数组的第一个字节开始!研究API ByteBuffer,你会明白发生了什么:内容从返回的值开始,arrayOffset()结束返回limit().