当前位置: 首页 > 知识库问答 >
问题:

JavaNio ByteBuffer在缓冲区达到其绑定时截断Unicode字符

羿经武
2023-03-14

我正在用java编写一个函数,可以读取文件并将其内容转换为字符串:

public static String ReadFromFile(String fileLocation) {
    StringBuilder result = new StringBuilder();
    RandomAccessFile randomAccessFile = null;
    FileChannel fileChannel = null;
    try {
        randomAccessFile = new RandomAccessFile(fileLocation, "r");
        fileChannel = randomAccessFile.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        CharBuffer charBuffer = null;
        int bytesRead = fileChannel.read(byteBuffer);
        while (bytesRead != -1) {
            byteBuffer.flip();
            charBuffer = StandardCharsets.UTF_8.decode(byteBuffer);
            result.append(charBuffer.toString());
            byteBuffer.clear();
            bytesRead = fileChannel.read(byteBuffer);
        }
    } catch (IOException ignored) {
    } finally {
        try {
            if (fileChannel != null)
                fileChannel.close();
            if (randomAccessFile != null)
                randomAccessFile.close();
        } catch (IOException ignored) {
        }
    }
    return result.toString();
}

从上面的代码中,您可以看到我设置了“ByteBuffer”。只分配10个字节,目的是让事情更清楚。现在我想读取一个名为“test.txt”的文件,该文件包含中文unicode字符,如下所示:

乐正绫我爱你乐正绫我爱你

下面是我的测试代码:

java prettyprint-override">System.out.println(ReadFromFile("test.txt"));

控制台中的预期输出

乐正绫我爱你乐正绫我爱你

控制台中的实际输出

乐正绫���爱你��正绫我爱你

可能原因
ByteBuffer只分配了10个字节,因此unicode字符每10个字节被截断一次。

尝试解决将ByteBuffer分配的字节数增加到20的问题,结果如下:

乐正绫我爱你��正绫我爱你

不是一个健壮的解决方案
将ByteBuffer分配给一个非常大的数字,如102400,但对于非常大的文本文件,它是不实用的。

问题
如何解决这个问题?

共有1个答案

黎浩然
2023-03-14

您不能,因为您不知道UTF-8编码中每个字符使用了多少字节,而且您真的不想重写该逻辑

有文件。Java 11中的readString(),对于较低版本,可以使用文件。readAllBytes()例如。

Path path = new File(fileLocation).toPath()
String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
 类似资料:
  • 问题内容: 我正在尝试启动并运行数据解析脚本。就数据操作而言,它起作用。我想要做的是设置此功能,以便我可以通过一个命令输入多个用户定义的CSV。 例如 如果您有关于如何自动输出CSV命名任何意见,这样,如果,我会很感激这一点。 得到 为线 我的代码: 我不太了解该错误的原因。有人可以用外行的术语解释吗? 请记住,我是一个整体的编程/ python新手,并且基本上是一个人学习,因此,如果可能的话,您

  • 问题内容: 我已经有很长时间了,但是无法解决这个错误: 渲染时捕获TypeError:强制转换为Unicode:需要字符串或缓冲区,找到NoneType 当我尝试在其中一个模型上添加或修改时,它会在管理员中发生(显示效果很好) 这是模型: 知道我在做什么错吗? 追溯: 问题答案: 当您使用的方法是返回未输入的字段时,会发生此错误。任何空白字段均为,Python无法转换,因此会出现错误。 在您的情况

  • 问题内容: 在编写用于OpenGL库的Matrix类时,我遇到了一个问题,即使用Java数组还是使用Buffer策略存储数据(JOGL为Matrix操作提供直接缓冲区复制)。为了对此进行分析,我编写了一个小型性能测试程序,该程序比较了Arrays vs Buffers和Direct Buffers上循环和批量操作的相对速度。 我想在这里与您分享我的结果(因为我发现它们很有趣)。请随时发表评论和/或

  • 简短版本:是否可以(通过Graphics2D)绘制到自定义缓冲区类(“稀疏”光栅图像)? 更长的版本:我想将多边形(由闭合路径给定)转换为光栅图像。 但是由于多边形可能非常大(这是一个研究项目),我必须使用稀疏存储(项目的这部分已经由我之前的人实现了) 由于实现(高效)光栅算法非常耗时,我想使用java已经提供的方法(例如Graphics2D),而不是绘制到BufferedImage中,尝试绘制到

  • 我在游戏中使用延迟渲染器。因此,第一个渲染过程是使用多个渲染rarget创建反照率和法线缓冲区,并填充深度缓冲区。所有这些缓冲区实际上都是纹理。 现在我想从其他渲染通道访问深度缓冲区,从而访问其他帧缓冲区,而不改变深度纹理。我只想读取深度值。对于这些通道,我主要绘制全屏四边形,我不希望他们更新深度纹理并将其消隐为深度值0。 如何将一个给定的深度纹理附加到另一个帧缓冲区,并确保它是只写的?

  • 纯JavaScript是Unicode友好的,但二进制数据却不是这样。 在处理TCP流或文件系统时,必须处理八位字节流。 Node提供了Buffer类,它提供了存储类似于整数数组的原始数据的实例,但对应于V8堆外部的原始内存分配。 Buffer类是一个全局类,可以在应用程序中访问而无需导入缓冲区模块。 创建缓冲区 节点缓冲区可以以多种方式构建。 Method 1 以下是创建10个八位字节的无启动缓