我知道这是一个非常普遍的问题,但我变得疯了。
我使用了这段代码:
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中转换编码?
答案 0 :(得分:7)
您的问题是ByteBuffer.array()
返回对用作ByteBuffer的后备存储的数组的直接引用,而不是后备数组的有效范围的副本。您必须服从bbuf.limit()
(正如Peter在回复中所做的那样),并且只使用索引0
到bbuf.limit()-1
的数组内容。
后备阵列中额外0值的原因是CharsetEncoder创建生成的ByteBuffer的方式存在轻微缺陷。每个CharsetEncoder都有一个“每个字符的平均字节数”,对于UCS2编码器来说,它看起来简单而正确(2个字节/字符)。遵循该固定值,CharsetEncoder最初分配具有“字符串长度*每个字符的平均字节数”字节的ByteBuffer,在这种情况下,例如, 10个字符长的字符串为20个字节。然而,UCS2 CharsetEncoder以BOM(字节顺序标记)开始,它也占用2个字节,因此10个字符中只有9个符合分配的ByteBuffer。 CharsetEncoder检测溢出并分配一个长度为2 * n + 1的新ByteBuffer(n是ByteBuffer的原始长度),在这种情况下为2 * 20 + 1 = 41字节。由于21个新字节中只有2个需要对剩余字符进行编码,因此从bbuf.array()
获得的数组长度为41个字节,但bbuf.limit()
表示实际只有前22个条目使用
答案 1 :(得分:4)
我不确定你是如何获得一系列null
字符的。试试这个
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(), 0, bbuf.limit(), charsetOutput));
打印
Hello World! £€