min*_*ins 6 java bytebuffer character-encoding
我正在尝试根据字符集整理字符,它们在字节序列中的表示,以及如何在Java中将一个字符集转换为另一个字符集.我有些困难.
例如,
ByteBuffer bybf = ByteBuffer.wrap("Olé".getBytes());
Run Code Online (Sandbox Code Playgroud)
我的理解是:
getBytes() 结果是相同的UTF-16字节序列 wrap() 保持这个顺序 bybf 因此是字符串的UTF-16大端表示 Olé 因此在这段代码中:
Charset utf16 = Charset.forName("UTF-16");
CharBuffer chbf = utf16.decode(bybf);
System.out.println(chbf);
Run Code Online (Sandbox Code Playgroud)
decode() 应该
bybf为UTF-16字符串表示 Olé. 实际上不应该改变任何字节,因为一切都是UTF-16存储的,而UTF-16 Charset应该是一种"中性算子".但结果打印为:
??
Run Code Online (Sandbox Code Playgroud)
怎么可能?
附加问题:为了正确转换,似乎Charset.decode(ByteBuffer bb)需要bb是字符串的UTF-16大端字节序列图像.那是对的吗?
编辑:从提供的答案,我做了一些测试来打印ByteBuffer内容和chars通过解码获得.字节[编码用= "Olé".getBytes(charsetName)]打印在第一行组上,另一行是通过Charset#decode(ByteBuffer)用各种方法解码字节[with ]而获得的字符串Charset.
我还确认byte[]在Windows 7计算机上存储String的默认编码是windows-1252(除非字符串包含需要UTF-8的字符).
Default VM encoding: windows-1252
Sample string: "Olé"
getBytes() no CS provided : 79 108 233 <-- default (windows-1252), 1 byte per char
Decoded as windows-1252: Olé <-- using the same CS than getBytes()
Decoded as UTF-16: ?? <-- using another CS (doesn't work indeed)
getBytes with windows-1252: 79 108 233 <-- same than getBytes()
Decoded as windows-1252: Olé
getBytes with UTF-8: 79 108 195 169 <-- 'é' in UTF-8 use 2 bytes
Decoded as UTF-8: Olé
getBytes with UTF-16: 254 255 0 79 0 108 0 233 <-- each char uses 2 bytes with UTF-16
Decoded as UTF-16: Olé (254-255 is an encoding tag)
Run Code Online (Sandbox Code Playgroud)
你大多是正确的.
java中的本机字符表示形式是UTF-16.但是,在将字符转换为字节时,您可以指定正在使用的字符集,或者系统使用它的默认值,每当我选中时,它通常都是UTF-8.如果您正在混合和匹配,这将产生有趣的结果.
例如,我的系统如下
System.out.println(Charset.defaultCharset().name());
ByteBuffer bybf = ByteBuffer.wrap("Olé".getBytes());
Charset utf16 = Charset.forName("UTF-16");
CharBuffer chbf = utf16.decode(bybf);
System.out.println(chbf);
bybf = ByteBuffer.wrap("Olé".getBytes(utf16));
chbf = utf16.decode(bybf);
System.out.println(chbf);
Run Code Online (Sandbox Code Playgroud)
产生
UTF-8
佬쎩
Olé
因此,如果UTF-16是默认字符集,则此部分才正确
getBytes() result is this same UTF-16 byte sequence.
因此,要么总是指定您正在使用的最安全的字符集,因为您将始终知道发生了什么,或者始终使用默认值.
字符串始终以Java格式存储为UTF-16字节序列(每个字符2个字节,大端)
是.
getBytes()结果是相同的UTF-16字节序列
不会.无论是什么,它都会将UTF-16字符编码到平台默认字符集中.已过时.
wrap()维护这个序列
wrap() 保持一切.
因此,bybf是字符串Olé的UTF-16大端表示
不.它包装了平台原始字符串的默认编码.
decode()应该
- 将bybf解释为UTF-16字符串表示
不,见上文.
- "将"转换为原始字符串Olé.
除非平台的默认编码是"UTF-16".
| 归档时间: |
|
| 查看次数: |
11251 次 |
| 最近记录: |