有没有办法对 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() 方法开始。
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() 方法开始。