java - 如何将一定数量的字节读入缓冲区?

标签 java performance buffer nio channel

以下问题:我有一个很大的文本文件,每行包含 13 个字节。我不想使用 InputStream 以常用方式逐行读取文件。我正在尝试使用 NIO Channels 和 MappedByteBuffers 以获得更好的性能和有限的资源。

到目前为止,这就是我所做的:

RandomAccessFile data = new RandomAccessFile("the_file.txt", "rw");
FileChannel channel = data.getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, capacity);

这里的容量 是 n*13,以确保只有整行适合缓冲区。 但这是行不通的!我这样填充缓冲区:

int bytesRead = channel.read(buffer);

但这并没有填满整个缓冲区! bytesRead 不等于 capacity,更糟糕的是在我的情况下 bytesRead%13 不是,这意味着它不包含整行,最后有些东西被切断了。 我怎样才能将一定数量的字节读入缓冲区?在我的例子中,我正好需要 n*13 个字节,这样原始行就不会被拆分...

最佳答案

快速浏览 documentation揭示有关 read 方法的真相。

A read operation might not fill the buffer, and in fact it might not read any bytes at all.

从这里可以很清楚地看出,不能假定 read 调用会填充缓冲区。要实现这一点,您需要创建一个循环,检查还有多少内容需要阅读:

while(buffer.remaining() > 0) channel.read(buffer);

在强大的 java 流 API 中,所有这些都是自动处理的。

我建议使用简单的 BufferedReader然后测量性能。然后您可以做出更明智的决定,再次尝试使用 NIO 类。您会对基于流的类的性能感到惊讶。该解决方案还将为您提供更易于维护和阅读的代码。

关于java - 如何将一定数量的字节读入缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8194103/

相关文章:

java - 如何为 Rest API 创建 SSL?

java - Android 中如何将用户输入从一个 Activity 传递到另一个 Activity

java - MySQL 的可查询缓存

c# - 提升Redis性能减少超时异常

java - 使用 Rserve 时由于错误太大而丢弃缓冲区

java - spring security : NoSuchBeanDefinitionException: No qualifying bean of type [org. springframework.security.config.annotation.ObjectPostProcessor] 找到

java - Akka Actor 和消息处理

c# - 不使用数据集的N层体系结构(数据集听起来对性能不利)

python - Linux : python : clear input buffer before raw_input()

带有法线的 DirectX 11 索引绘图