java - 在 Java : null characters with CharsetDecoder/Encoder 中从 Windows 1252 转换为 UTF8

标签 java encoding

我知道这是一个非常笼统的问题,但我快要生气了。

我使用了这段代码:

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中有没有更好的编码转换方式?

最佳答案

您的问题是 ByteBuffer.array() 返回对用作 ByteBuffer 后备存储的数组的直接引用,而不是后备数组有效范围的副本。你必须遵守 bbuf.limit()(正如 Peter 在他的回应中所做的那样)并且只使用从索引 0bbuf.limit() 的数组内容- 1

支持数组中额外的 0 值的原因是 CharsetEncoder 如何创建生成的 ByteBuffer 的方式存在轻微缺陷。每个 CharsetEncoder 都有一个“每个字符的平均字节数”,这对于 UCS2 编码器来说似乎简单而正确(2 个字节/字符)。根据这个固定值,CharsetEncoder 最初分配一个 ByteBuffer,其中包含“字符串长度 * 每个字符的平均字节数”字节,在这种情况下,例如10 个字符长的字符串需要 20 个字节。然而,UCS2 CharsetEncoder 以 BOM(字节顺序标记)开始,它也占用 2 个字节,因此 10 个字符中只有 9 个适合分配的 ByteBuffer。 CharsetEncoder 检测到溢出并分配一个长度为 2*n+1(n 是 ByteBuffer 的原始长度)的新 ByteBuffer,在本例中为 2*20+1 = 41 字节。由于只需要 21 个新字节中的 2 个来编码剩余的字符,您从 bbuf.array() 获得的数组长度为 41 个字节,但是 bbuf.limit() 将指示实际仅使用前 22 个条目。

关于java - 在 Java : null characters with CharsetDecoder/Encoder 中从 Windows 1252 转换为 UTF8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6127528/

相关文章:

java - 编码字符串在java中不能正常工作

java - 字节数组的最短字符串编码

Haskell 源编码

python - 在 django live 应用程序中将 mysql 数据库从 'utf8' 更改为 'utf8mb4' 对数据的影响

java - 是否有一个 Eclipse 快捷方式就像使用鼠标双击一样?

java - Hibernate 无法初始化代理 - 没有 session

java - Jenkins 不运行我的 Selenium 测试 ('No tests to run' )

java - 最后的预期计算与测试仪不匹配。我的 setDimensions 方法有什么问题吗?

php - ISO-8859-1 字符截断插入到 utf-8 mysql 列中的文本

java - 如何在java中将二维数组坐标存储在列表中