java - Java NIO 解码过程中如何去掉不正确的符号?

标签 java decode nio

我需要从文件中读取文本,例如在控制台中打印它。该文件采用 UTF-8 格式。看来我做错了什么,因为一些俄语符号打印不正确。我的代码有什么问题吗?

StringBuilder content = new StringBuilder();

        try (FileChannel fChan = (FileChannel) Files.newByteChannel(Paths.get("D:/test.txt")) ) {

            ByteBuffer byteBuf = ByteBuffer.allocate(16);
            Charset charset = Charset.forName("UTF-8");

            while(fChan.read(byteBuf) != -1) {
                byteBuf.flip();
                content.append(new String(byteBuf.array(), charset));
                byteBuf.clear();
            }

            System.out.println(content);
        } 

结果:

Здравствуйте, как поживае��е?
Это п��имер текста на русском яз��ке.ом яз�

实际文本:

Здравствуйте, как поживаете?
Это пример текста на русском языке.

最佳答案

UTF-8 每个字符使用可变的字节数。这会给你带来一个边界错误:你将基于缓冲区的代码与基于字节数组的代码混合在一起,并且你不能在这里这样做;您可能会读取足够多的字节来卡在一个字符中,然后将输入转换为字节数组并进行转换,这会失败,因为您无法转换半个字符。

您真正想要的是首先读取所有数据,然后转换整个输入,或者,当您翻转时将任何半字符保留在字节缓冲区中,或者更好的是,放弃所有这些内容并使用以下代码被写入以读取实际字符。一般来说,使用 channel API 会使事情变得非常复杂;它很灵活,但很复杂 - 就是这样。

除非您能解释为什么需要它,否则不要使用它。改为这样做:

Path target = Paths.get("D:/test.txt");
try (var reader = Files.newBufferedReader(target)) {
    // read a line at a time here. Yes, it will be UTF-8 decoded.
}

或者更好,因为你显然想一口气读完整本书:

Path target = Paths.get("D:/test.txt");
var content = Files.readString(target);

注意:与大多数将字节转换为字符或反之亦然的 java 方法不同,Files API 默认为 UTF-8(而不是无用且危险、无法测试错误的“平台默认编码”) ' 大多数 java API 都是这样做的)。这就是为什么这最后一个极其简单的代码仍然是正确的。

关于java - Java NIO 解码过程中如何去掉不正确的符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64728361/

相关文章:

java - 如何在 SmartOS 上使用 HotSpot DTrace 探测器?

decode - Informatica 中的 Case 语句/解码函数

javascript - 在 JavaScript 中解码 url 字符串

Java nio : How to add extension to an absolute path?

java - 如何跳转到特定行并从 java 中读取

java - 如何获取控制台输出(例如在 eclipse 上)并将相同的输出写入/复制到文件?

Java - 默认接口(interface)方法不能充当其他接口(interface)方法的实现

Java - LinkedList 中的 "Rotating"对象 - LinkedList.addLast(LinkedList.removeFirst()) 是好编程还是坏编程?

java - 使用 Selenium 从 XML 文件填写表单

c# - 使用 Rijndael 进行跨平台(php 到 C# .NET)加密/解密