RandomAccessFile具有超越Long的支持?

2022-09-02 21:38:49

我目前正在使用 一个实例来管理一些内存中数据,但我的实例的大小超过 2^64 字节,因此我无法使用诸如 和 之类的方法,因为它们使用并且无法管理大于 2^64 的地址空间。那我该怎么办?我还可以使用其他支持超过2 ^ 64的地址空间的东西吗?RandomAccessFileRandomAccessFileseek()write()Long

编辑:问这个问题的原因:

我有一个树数据结构,理论上最多可以有2 ^ 128个节点,我想将此树存储到一个文件中。每个节点的数据大约为 6 个字节。所以我想知道如何存储这棵树到文件。


答案 1

这不是一个正确的答案,但你确定你的文件实际上这么大吗?

来自 Long.MAX_VALUE 的文档

一个常量,用于保存长头可以具有的最大值 2^63-1。

来自 RandomAccessFile.length() 的文档

此文件的长度,以字节为单位。

你知道2^63-1是多少字节吗?相反,9,223,372,036,854,775,807字节?

9,223,372,036,854,775,807 B
9,223,372,036,854,775    KB
9,223,372,036,854        MB
9,223,372,036            GB
9,223,372                TB
9,223                    PB
9                        EB

如果我的数学正确,你需要一个大约272GB / s的恒定写入速度1年。

虽然这是一个我希望看到答案的极好问题,但我非常怀疑您是否有一个大小为9EB的文件,如果操作系统甚至支持这一点。

编辑

以下是一些文件系统限制,令我自己惊讶的是,NTFS实际上支持高达16EiB的单个文件,但这只是列表中唯一支持它的少数几个文件之一。


如果你绝对需要访问一个大于9EiB的文件,看起来你可能需要滚动你自己的RandomAccessFile版本,使用BigInteger,而另一个版本使用长。这可以使你达到 (2 ^ 32) ^ Integer.MAX_VALUE 字节。


答案 2

我想你的问题源于这个要求“我还能用别的东西来支持超出地址空间”。换句话说,您希望按地址访问内存,并且您的地址可能很大。

当然,你不应该分配2 ^ 128 * 6字节的文件,即使现在有可能,它也太昂贵了。这里的典型方法是将存储拆分为较小的部分,并相应地对其进行处理。例如

write(partition, address, node);
node = read(partition, address);

正如你所说,你应该存储IPv6地址。要存储IPv6并快速搜索它,就足以为ipv6地址的每个部分创建一个包含8列和索引的表。或者,您可以在树层次结构中存储信息,例如:

  • 0000
    • 0000
      • 0000
    • 0001
      • 0000

应按需分配。因此,真正的问题应该是如何有效地组织存储。

更新

我想指出的是,实际上Java中有私有API(Oracle JDK,而不是OpenJDK),它可以给你一个机会来处理超过2 Gb的文件,但它是私有的,根本不是公共API的一部分,所以我不会在这里描述它,没有请求。你可以直接在sun.nio.ch.FileChannelImpl(私有map0,unmap0方法)中找到它。


推荐