bop*_*cat 1 java character-encoding
代码段:
public static void main(String[] args) {
String s = "qwertyuiop";
System.out.println(Arrays.toString(Charset
.forName("UTF-8")
.encode(s)
.array()));
}
Run Code Online (Sandbox Code Playgroud)
打印:
[113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 0]
Run Code Online (Sandbox Code Playgroud)
这似乎发生了,因为在引擎盖下,在java.nio.charset.CharsetEncoder类中,averageBytesPerChar变量对于UTF-8似乎是1.1.因此它分配11个字节而不是10个字节,如果输入字符串只包含好的旧单字节字符,我最后得到奇数空字符.
我想知道这是否记录在任何地方?
这一页:
https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html#encode(java.lang.String)
没有提供有关此类行为的线索.
PS我是否正确无论如何,上述代码段最好由以下代码替换:
s.getBytes(StandardCharsets.UTF_8)
Run Code Online (Sandbox Code Playgroud)
我从它的来源看到的还修剪结果以避免那些空字符?
那么,java.nio.charset.Charset的编码(String s)应该用于什么?
Charset.encode()
,但是Buffer.array()
.如果你打印Charset.forName("UTF-8").encode(s)
,你会发现输出
java.nio.HeapByteBuffer[pos=0 lim=10 cap=11]
Run Code Online (Sandbox Code Playgroud)
ByteBuffer具有限制10(字符串的长度)和容量 11(缓冲区的总分配大小).如果您更改编码,限制和容量可能会有更大的变化,例如
System.out.println(Charset.forName("UTF-16").encode(s));
// java.nio.HeapByteBuffer[pos=0 lim=22 cap=41]
// (2 extra bytes because of the BOM, not null-termination)
Run Code Online (Sandbox Code Playgroud)
当您调用时.array()
,它将返回整个后备阵列,因此即使超出限制的内容也将包含在内.
提取Java字节数组的实际方法是通过以下.get()
方法:
ByteBuffer buf = Charset.forName("UTF-8").encode(s);
byte[] encoded = new byte[buf.limit()];
buf.get(encoded);
System.out.println(Arrays.toString(encoded));
Run Code Online (Sandbox Code Playgroud)
那看起来像一团糟?因为"NIO"是指Ñ ative I/O.创建Buffer类型,以便它可以轻松地包装C数组.它使得与本机代码交互(例如读/写文件或发送/接收网络数据)非常有效.这些NIO API通常Buffer
直接使用,而不byte[]
在其间构建任何内容.如果你只是在使用Buffer
,中间的两行不需要存在:).
如果整个操作都在Java中,那么只需调用即可s.getBytes(StandardCharsets.UTF_8)
.
归档时间: |
|
查看次数: |
2323 次 |
最近记录: |