有没有办法在Java中使用大于Integer.MAX_VALUE的内存映射文件?

时间:2017-11-22 14:59:57

标签: java java-native-interface mmap memory-mapped-files mappedbytebuffer

FileChannel#map,用于映射文件(即启动内存映射),将long作为长度参数。

然而,the documentation on FileChannel#map说了以下内容:

  

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

首先,如果他们只允许最多Integer.MAX_VALUE的值,为什么他们首先使用long? 是否有可能一次映射大于该文件的文件?

例如,如果我想映射一个10GB的文件,我想写这样的东西(由于篇幅太长,最终会出现在InvalidArgumentException中):

long length = 10_000_000_000;
MappedByteBuffer buffer = (new RandomAccessFile("./memory.map", "rw")).getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);

我是否必须为此创建连续的内存映射,例如,每个映射2GB给定文件的5个内存映射?

2 个答案:

答案 0 :(得分:2)

FileChannel #map将返回ByteBuffer的实例, (MappedByteBuffer)如果你看一下,你可以看到它的方法专门使用int来索引数据,例如:

  

abstract byte get(int index)绝对get方法。

也定义了map本身的限制。

因此,您必须逐个映射文件或使用某些现有库,例如https://github.com/xerial/larray,用于映射更大的文件,该文件使用JNI映射文件> 2GB,并使用long数据指针提供它自己的缓冲区抽象。

还有一个选择是使用不安全的操作,如here所述。

答案 1 :(得分:1)

JDK14通过引入外部存储器访问API(JEP 383)预览版,为FileChannel API的这种限制提供了一种新的解决方案。请参阅MemorySegment.mapFromPath()方法开始。