我目前正在使用RandomAccessFile
的实例来管理一些内存数据,但我的RandomAccessFile
实例的大小超过了2 ^ 64字节,所以我不能使用这样的方法作为seek()
和write()
,因为他们使用Long
并且无法管理大于2 ^ 64的地址空间。那我该怎么办?还有什么我可以使用它支持超过2 ^ 64的地址空间吗?
编辑:提出此问题的原因:
我有一个Tree数据结构,理论上可以有多达2 ^ 128个节点,我想将这个树存储到一个文件中。每个节点具有大约6个字节的数据。所以我想知道如何将这个树存储到文件中。
答案 0 :(得分:16)
不是一个正确的答案,但你确定你的文件真的很大吗?
来自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的文件,如果操作系统甚至支持这个。
修改的
以下是一些File System Limits,令我惊讶的是,NTFS 将实际上支持最高16EiB的单个文件,但这只是列表中的少数几个之一支持它。
如果您绝对需要访问大于9EiB的文件,看起来您可能需要使用BigInteger滚动您自己的RandomAccessFile版本,而另一个使用较长的文件。这可以让你达到(2 ^ 32) ^ Integer.MAX_VALUE
个字节。
答案 1 :(得分:3)
我认为你的问题源于这个要求“我还能用什么来支持地址空间”。 换句话说,您希望按地址访问内存,并且您的地址可能很大。
当然,你不应该分配2 ^ 128 * 6字节的文件,即使现在有可能,它也会太昂贵。这里的典型方法是将存储分成较小的部分并相应地进行处理。 例如
write(partition, address, node);
node = read(partition, address);
正如您所说,您应该存储IPv6地址。要存储IPv6并快速搜索,就可以为ipv6地址的每个部分创建一个包含8列和索引的表。或者您可以在树形层次中存储信息,如:
您应该按需分配。所以真正的问题应该是如何有效地组织存储。
更新
我想要注意的是,实际上Java中有私有API(Oracle JDK,而不是OpenJDK),这可以让您有机会处理超过2 Gb的文件,但它是私有的,不是公共API的一部分根本没有要求,所以我不会在这里描述。您可以直接在sun.nio.ch.FileChannelImpl(私有map0,unmap0方法)中找到它。
答案 2 :(得分:2)
即使你有软件做这样的事情,它也会在你建议的规模上无法使用,因为没有一台机器有这么大的磁盘空间。
因此,由于主要问题是单个机器的硬件限制,因此解决方案是使用分布式计算框架,允许您根据需要进行扩展。我建议使用https://ignite.apache.org/非常灵活,并且在堆栈溢出方面有相当不错的支持。
从另一个角度来看,您希望存储IPv6 IP地址。在理论层面,确定你需要2 ^ 64个地址。在实际层面上,即使您尝试将每个IP索引到今天,也不会显着传递2 ^ 32,因为这是IPv4地址的数量,我们正在通过该限制。