内存映射文件java NIO

时间:2012-02-03 01:30:44

标签: java nio memory-mapped-files

我理解如何创建内存映射文件,但我的问题是让我们说在以下行中:

FileChannel roChannel = new RandomAccessFile(file, "r").getChannel();
ByteBuffer roBuf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, SIZE);

例如,我将SIZE设置为2MB,这是否意味着它只会加载2MB的文件,或者它会在文件中进一步读取并更新缓冲区,因为我从中消耗了字节数?

2 个答案:

答案 0 :(得分:4)

  

例如,我将SIZE设置为2MB,这是否意味着它只会加载2MB的文件,或者它会在文件中进一步读取并更新缓冲区,因为我从中消耗了字节数?

它只会加载缓冲区初始化中指定的文件部分。如果你想进一步阅读,你需要有一些读取循环。虽然我不会说这很棘手,如果一个人不熟悉所涉及的java.io和java.nio API,那么填充它的可能性很高。 (例如:不翻转缓冲区;缓冲区/文件边缘错误)。

如果您正在寻找一种在ByteBuffer中访问此文件的简便方法,请考虑使用MappedByteBuffer

RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel fc = raf.getChannel();
MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

在这种情况下使用MBB的好处是它不一定会将整个缓冲区实际加载到内存中,而只是加载你正在访问的部分。

答案 1 :(得分:2)

缓冲区的大小是您传入的大小。它不会增长或缩小。

javadoc说:

  

将此频道文件的某个区域直接映射到内存中。

     

...

     

size - 要映射的区域的大小;必须是非负数且不大于Integer.MAX_VALUE

编辑:

根据“使用新数据更新”的含义,答案是肯定的。

  

此类的实例提供的文件视图保证与同一程序中其他实例提供的同一文件的其他视图一致。然而,由于底层操作系统执行的高速缓存和网络文件系统协议引起的延迟,该类实例提供的视图可能会也可能不会与其他同时运行的程序所看到的视图一致。无论这些其他程序的编写语言是什么,以及它们是在同一台机器上运行还是在其他机器上运行,都是如此。任何此类不一致的确切性质都取决于系统,因此未指明。

因此,其他系统可能会进行缓存,但是当这些缓存被刷新或以其他方式更新时,它们将同意FileChannel提供的视图。

您还可以使用对position方法的显式调用和其他方法来更改视图显示的内容。

  

更改通道的位置,无论是显式还是通过读取或写入字节,都将更改原始对象的文件位置,反之亦然。通过文件通道更改文件长度将改变通过原始对象看到的长度,反之亦然。通过写入字节来更改文件的内容将改变原始对象看到的内容,反之亦然。