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

Posted

技术标签:

【中文标题】有没有办法在 Java 中映射大于 Integer.MAX_VALUE 的文件?【英文标题】:Is there a way to memory-map files in Java that are larger than Integer.MAX_VALUE? 【发布时间】:2017-11-22 14:59:57 【问题描述】:

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);

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于有没有办法在 Java 中映射大于 Integer.MAX_VALUE 的文件?的主要内容,如果未能解决你的问题,请参考以下文章

从 Java 8 映射操作返回空元素

Hibernate映射java的boolean类型

oracle 中的啥数据类型会映射到 Java int?

使用 Java 映射大于 2GB 的文件

在java 8中将地图映射转换为单个值列表[关闭]

java JPA with Hibernate模糊查询时类型为Long型出错