1

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

然而,关于文档FileChannel#map的内容如下:

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

首先,如果他们只允许高达 的值,为什么他们首先使用 long Integer.MAX_VALUE?是否有可能一次映射比这更大的文件?

例如,如果我想映射一个 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 给定文件?

4

2 回答 2

3

FileChannel#map 将返回一个ByteBuffer实例(MappedByteBuffer) ,如果您查看它,您会发现它是专门用于int索引数据的方法,例如:

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

map这也为自己定义了限制。

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

另一种选择是使用 Unsafe 操作,如此所述。

于 2017-11-22T15:11:06.820 回答
2

JDK14 通过引入 Foreign-Memory Access API (JEP 383) 预览版为 FileChannel API 的这一限制提供了新的解决方案。请参阅MemorySegment.mapFromPath()方法以开始使用。

于 2020-07-29T20:55:07.463 回答