在 Java 中映射大型文件的内存映射

2022-09-04 20:20:23

是否可以在Java中内存映射大型文件(多个GB)?

这种方法看起来很有希望:FileChannel

MappedByteBuffer map(FileChannel.MapMode mode, long position, long size)

两者都允许64位值 - 到目前为止,一切都很好。positionsize

MappedByteBuffer但是,仅提供 32 位位置(、 等)的方法,这似乎暗示我无法映射大于 2 GB 的文件。get(int index)position(int newPosition)

如何绕过此限制?


答案 1

看看使用内存映射文件获取一个巨大的矩阵代码,它显示了如何创建一个列表,每个列表小于2 GB,以映射整个文件:MappedByteBuffer

private static final int MAPPING_SIZE = 1 << 30;
...
long size = 8L * width * height;
for (long offset = 0; offset < size; offset += MAPPING_SIZE) {
    long size2 = Math.min(size - offset, MAPPING_SIZE);
    mappings.add(raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size2));
}

根据 JDK-6347833 (fs) 增强映射字节缓冲区,以支持 64 位平台上>2GB 的大小,限制为 2 GB 的原因是:

MappedByteBuffer 是具有其他操作以支持内存映射文件区域的 ByteBuffer。若要支持映射大于 Integer 的区域.MAX_VALUE,需要类的并行层次结构。目前,唯一的解决方案是创建多个MappedByteBuffers,其中每个都对应于一个不大于2GB的区域。


答案 2

如前所述,由于使用整数索引/位置指针,因此具有2GB的限制。MappedByteBuffer

要解决这个问题,你可以使用像larray这样的替代实现。


推荐