我试图根据字符集来整理字符、它们在字节序列中的表示,以及如何在Java中从一个字符集转换到另一个字符集。我有一些困难。
例如,
ByteBuffer bybf = ByteBuffer.wrap("Olé".getBytes());我的理解是:
getBytes()结果是相同的UTF-16字节序列。wrap()维护此序列bybf是字符串Olé的UTF-16大端表示形式。因此,在本代码中:
Charset utf16 = Charset.forName("UTF-16");
CharBuffer chbf = utf16.decode(bybf);
System.out.println(chbf); decode()应该
bybf解释为UTF-16字符串表示。Olé。实际上,不应该改变任何字节,因为所有东西都存储在UTF-16中,而UTF-16 Charset应该是一种“中性运算符”。然而,结果被打印为:
??,怎么可能?
附加问题:为了正确转换,Charset.decode(ByteBuffer bb)似乎需要bb是一个字符串的UTF-16大字节序列图像。是对的吗?
编辑:根据提供的答案,我做了一些测试来打印ByteBuffer内容和通过解码得到的chars。使用="Olé".getBytes(charsetName)编码的字节被打印在组的第一行上,另一行(S)是通过用不同的Charset#decode(ByteBuffer)对字节进行解码而得到的字符串。
我还确认,在Windows7计算机上将字符串存储到byte[]中的默认编码是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)发布于 2014-06-30 01:54:28
你基本上是对的。
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);产生
UTF-8
佬쎩
欧蕾
因此,只有当UTF-16是默认字符集时,此部分才是正确的。
getBytes() result is this same UTF-16 byte sequence.
因此,要么始终指定您正在使用的字符集,这是最安全的,因为您将始终知道发生了什么,或者始终使用默认值。
发布于 2014-06-30 06:04:20
字符串总是以UTF-16字节顺序存储在Java中(每个字符2字节,大端)
是。
getBytes()结果是相同的UTF-16字节序列
不是的。它将UTF-16字符编码到平台默认字符集中,不管是什么。不赞成。
wrap()维护此序列
wrap()维护一切。
因此,bybf是字符串Olé的UTF-16大端表示形式。
不是的。它封装了平台原始字符串的默认编码。
解码()应该
不,看上面。
除非平台的默认编码是"UTF-16“。
发布于 2015-07-08 07:16:42
对于双字节字符集编码的数据,我也遇到了几乎相同的问题。上面的答案3已经包含了你应该注意的关键问题。
以下代码工作
public static String convertUTF16ToString(byte[] doc)
{
final Charset doublebyte = StandardCharsets.UTF_16;
// Don't need this because it is my local (system default).
//final Charset ansiCharset = StandardCharsets.ISO_8859_1;
final CharBuffer encoded = doublebyte.decode(ByteBuffer.wrap(doc));
StringBuffer sb = new StringBuffer(encoded);
return sb.toString();
}用您喜欢的编码替换系统默认设置。
public static String convertUTF16ToUTF8(byte[] doc)
{
final Charset doublebyte = StandardCharsets.UTF_16;
final Charset utfCharset = StandardCharsets.UTF_8;
final Charset ansiCharset = StandardCharsets.ISO_8859_1;
final CharBuffer encoded1 = doublebyte.decode(ByteBuffer.wrap(doc));
StringBuffer sb = new StringBuffer(encoded1);
final byte[] result = ansiCharset.encode(encoded1).array();
// alternative to utf-8
//final byte[] result = utfCharset.encode(encoded1).array();
return new String(result);
}https://stackoverflow.com/questions/24481238
复制相似问题