如何解决从Windows 1252到Java的UTF8转换:使用CharsetDecoder / Encoder的空字符
| 我知道这是一个非常普遍的问题,但我正在发疯。 我使用以下代码:String ucs2Content = new String(bufferToConvert,inputEncoding);
byte[] outputBuf = ucs2Content.getBytes(outputEncoding);
return outputBuf;
但是我读到最好使用CharsetDecoder和CharsetEncoder(我的内容中的某些字符可能在目标编码之外)。我刚刚编写了这段代码,但是有一些问题:
// Create the encoder and decoder for Win1252
Charset charsetInput = Charset.forName(inputEncoding);
CharsetDecoder decoder = charsetInput.newDecoder();
Charset charsetOutput = Charset.forName(outputEncoding);
CharsetEncoder encoder = charsetOutput.newEncoder();
// Convert the byte array from starting inputEncoding into UCS2
CharBuffer cbuf = decoder.decode(ByteBuffer.wrap(bufferToConvert));
// Convert the internal UCS2 representation into outputEncoding
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(cbuf));
return bbuf.array();
的确,此代码将一个空字符序列附加到缓冲区中!
有人可以告诉我问题出在哪里吗?我不太擅长Java编码转换。
有没有更好的方法来转换Java编码?
解决方法
您的问题是,“ 2”返回对用作ByteBuffer的后备存储的数组的直接引用,而不是后备数组有效范围的副本。您必须服从
bbuf.limit()
(就像Peter在他的回答中所做的那样),并且只使用索引0
到bbuf.limit()-1
的数组内容。
支持数组中额外的0值的原因是CharsetEncoder如何创建结果ByteBuffer的一个小缺陷。每个CharsetEncoder具有一个“每个字符平均字节”,对于UCS2编码器来说,这似乎是简单而正确的(每字节2个字节)。遵循此固定值,CharsetEncoder最初会分配一个ByteBuffer,其长度为“字符串长度*每个字符的平均字节数”字节,在这种情况下,例如10个字符长的字符串20个字节。但是,UCS2 CharsetEncoder以BOM(字节顺序标记)开头,该BOM也占用2个字节,因此10个字符中只有9个适合分配的ByteBuffer。 CharsetEncoder检测到溢出并分配一个新的ByteBuffer,其长度为2 * n + 1(n是ByteBuffer的原始长度),在这种情况下为2 * 20 + 1 = 41字节。由于21个新字节中只有2个需要编码其余字符,因此从bbuf.array()
获得的数组长度为41字节,但是bbuf.limit()
表示仅实际使用了前22个条目。
,我不确定如何获得8个字符的序列。尝试这个
String outputEncoding = \"UTF-8\";
Charset charsetOutput = Charset.forName(outputEncoding);
CharsetEncoder encoder = charsetOutput.newEncoder();
// Convert the byte array from starting inputEncoding into UCS2
byte[] bufferToConvert = \"Hello World! £€\".getBytes();
CharBuffer cbuf = decoder.decode(ByteBuffer.wrap(bufferToConvert));
// Convert the internal UCS2 representation into outputEncoding
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(cbuf));
System.out.println(new String(bbuf.array(),bbuf.limit(),charsetOutput));
版画
Hello World! £€
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。