如何使用 ReadableByteChannel 获取文件内容并将其存储在 byteBuffer 中?

Posted

技术标签:

【中文标题】如何使用 ReadableByteChannel 获取文件内容并将其存储在 byteBuffer 中?【英文标题】:How can I use ReadableByteChannel to get file contents and store it in byteBuffer? 【发布时间】:2012-02-19 21:06:49 【问题描述】:

下面是我写的代码。我想做简单的事情,将二进制文件数据存储到 byteBuffer 中。

File file = new File(fileName);
try 
    ReadableByteChannel channel = new FileInputStream(fileName).getChannel();
    ByteBuffer buf = ByteBuffer.allocateDirect(file.length());

    // How can use buf.read to get all the contents?

 catch (Exception e)


我想知道

    如何使用read从通道中获取所有数据并将其存储在ByteBuffer中 如果有更优雅的方式来分配ByteBuffer,而不是使用File 对象来获取文件的长度

【问题讨论】:

【参考方案1】:

我更喜欢使用内存映射。

FileChannel channel = new FileInputStream(fileName).getChannel();
ByteBuffer buf = channel.map(MapMode.READ_ONLY,0,channel.size());

如果文件大于 2 GB,则必须有多个映射。从好的方面来说,无论文件大小如何,这大约需要 10 毫秒,并且无论文件大小如何,都不会使用太多堆或直接内存。

【讨论】:

【参考方案2】:

来自ReadableByteChannel Javadocs

读取(ByteBuffer dst) 尝试从通道读取最多 r 个字节,其中 r 是在调用此方法时缓冲区中剩余的字节数,即 dst.remaining()。

所以...channel.read(buf);

关于你的第二个问题,如果你想一次将文件的全部内容读入内存,这似乎是一种合理的方法。

【讨论】:

非常感谢。那么,使用文件长度分配 ByteBuffer 会安全地将所有文件内容读取到 ByteBuffer 中吗? 我没有亲自尝试过,但我看不出有什么理由不这样做;这就是您需要读取的数据量。 (问题不是安全问题,而是“我是否一举获得所有数据”) 我认为这并不可靠。 ReadableByteChannel 有权返回少于剩余字节数。来自 Javadoc “读取操作可能不会填充缓冲区,实际上它可能根本不会读取任何字节。”我认为您需要编写自己的 readFully 版本。 @ChristianSchlichtherle - 继续阅读该段的其余部分,而不是停在那里。特别是关于文件通道的部分。 @Brian Roach:“......文件通道不能读取超过文件中剩余的字节数。” - 这就是它所说的一切。我知道 FileChannel 将满足整个读取请求,但本着防御性编程的精神,我不会依赖它。下次有人使用该代码从另一个频道读取数据时,这一切都可能很容易被破坏。

以上是关于如何使用 ReadableByteChannel 获取文件内容并将其存储在 byteBuffer 中?的主要内容,如果未能解决你的问题,请参考以下文章

20145234黄斐《Java程序设计》第八周

文件channel用法

java.nio.channels的通道定义

[精选] Mysql分表与分库如何拆分,如何设计,如何使用

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话