有没有办法对 Java 中大于 Integer.MAX_VALUE 的文件进行内存映射?

Is there a way to memory-map files in Java that are larger than Integer.MAX_VALUE?

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

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

size - The size of the region to be mapped; must be non-negative and no greater than 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);

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

FileChannel#map 将 return ByteBuffer 的实例, (MappedByteBuffer) 如果你看它,你会发现它的方法专门使用 int 来索引数据,例如:

abstract byte get(int index) Absolute get method.

它也定义了 map 本身的限制。

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

另一种选择是使用不安全操作,如here所述。

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