java - 使用缓冲区将字符串转换为 UTF-8

标签 java unicode utf-8 character-encoding buffer

我需要将一个(可能很大)字符串转换为 UTF-8,但我不想创建包含完整编码的字节数组。我的想法是使用 CharsetEncoder 来实现此目的,但是 CharsetEncoder 仅作用于 CharBuffer,这意味着补充字符(在 Unicode 范围之外 >0x00000xFFFF)应予以考虑。

现在我使用的方法是CharBuffer.wrap(String.substring(start, start + BLOCK_SIZE)),以及我的ByteBuffer使用 ByteBuffer.allocate((int) Math.ceil(encoder.maxBytesPerChar() * BLOCK_SIZE)) 创建。但是,CharBuffer 现在将包含 BLOCK_SIZE 代码点,而不是代码单元(字符);我认为实际字符数将是最大值的两倍 BLOCK_SIZE。这意味着我的 ByteBuffer 也小了两倍。

如何计算 ByteBuffer 的正确字节数?如果每个字符都是补充字符,我可以简单地将其加倍,但这似乎有点多。但唯一的其他合理选项似乎是迭代所有代码单元(字符)或代码点,这至少看起来不是最理想的。

关于对字符串进行分段编码的最有效方法有什么提示吗?我应该使用缓冲区、使用 String.codePointAt(location) 进行迭代,还是有直接处理代码点的编码例程?

<小时/>

附加要求:无效的字符编码应导致异常,不允许默认替换或跳过无效字符。

最佳答案

似乎更容易简单地包装整个字符串,然后盲目地读取字符,直到没有剩余的为止。无需将字符串分成几部分,编码器将只读取字节,直到输出缓冲区被填满:

final CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder();
final CharBuffer buffer = CharBuffer.wrap(input);
final ByteBuffer encodedBuffer = ByteBuffer.allocate(BUFFER_SIZE);
CoderResult coderResult;

while (buffer.hasRemaining()) {
    coderResult = encoder.encode(buffer, encodedBuffer, false);
    if (coderResult.isError()) {
        throw new IllegalArgumentException(
                "Invalid code point in input string");
    }
    encodedBuffer.flip();
    // do stuff with encodedBuffer
    encodedBuffer.clear();
}

// required by encoder: call encode with true to indicate end
coderResult = encoder.encode(buffer, encodedBuffer, true);
if (coderResult.isError()) {
    throw new IllegalArgumentException(
            "Invalid code point in input string");
}
encodedBuffer.flip();
// do stuff with encodedBuffer
encodedBuffer.clear(); // if still required

关于java - 使用缓冲区将字符串转换为 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23984340/

相关文章:

java - 有没有办法对 AtomicReference 设置锁定

java - 如何将从 MongoDB 查询获得的年份和星期转换为 Joda 日期时间?

qt - 国际语言的 WrapMode 问题

html - 如何使用 Servlet 从 HTML 表单中检索 URDU 数据(UTF-8)以插入 MYSQL 数据库

java - spring freemarker ConversionNotSupportedException

javascript - 如何在 javascript 中使用 unicode 和 utf-8 解码字符串?

arrays - 将 unicode 代码点数组转换为字符串

javascript - 在 Javascript 中执行 new Date.toString() 时出现错误字符

mysql - 不区分重音的搜索/utf8_general_ci 排序规则问题

java - JBoss 7.1.1.Final 的 JSF 实现版本是多少?