Java创建字节数组,其大小由long表示

时间:2009-07-01 23:47:08

标签: java arrays byte long-integer

我正在尝试创建一个大小为long的字节数组。例如,将其视为:

long x = _________;
byte[] b = new byte[x]; 

显然,您只能为字节数组的大小指定int

在有人问为什么我需要一个如此大的字节数组之前,我会说我需要封装我没有编写的消息格式的数据,并且其中一个消息类型的长度为unsigned int({{ Java中的1}}。

有没有办法创建这个字节数组?

我在想如果没有办法解决它,我可以创建一个字节数组输出流并继续输入它的字节,但我不知道是否对字节数组的大小有任何限制......

5 个答案:

答案 0 :(得分:23)

(OP可能有点晚了,但对其他人来说可能仍然有用)

不幸的是,Java不支持超过2个 31 -1元素的数组。对于byte[]数组,最大消耗为2 GiB空间,对于long[]数组,最大消耗为16 GiB。

虽然在这种情况下它可能不适用,但如果数组将是sparse,您可能可以使用像Map这样的关联数据结构来匹配每个使用的数组偏移到适当的值。此外,与标准Java集合相比,Trove为存储原始值提供了更高内存效率的实现。

如果数组不是稀疏的并且您确实需要内存中的整个blob,那么您可能必须使用二维结构,例如将Map匹配偏移量模数为1024到正确的1024字节数组。即使对于稀疏数组,这种方法可能更有效,因为相邻的填充单元可以共享相同的Map条目。

答案 1 :(得分:6)

大小为最大32位有符号整数的byte[]将需要2GB的连续地址空间。您不应该尝试创建这样的数组。否则,如果大小不是那么大(并且它只是一个更大的类型),你可以安全地将其转换为int并使用它来创建数组。

答案 2 :(得分:1)

您可能应该使用流来读取您的数据而使用另一个流来写出来。如果您需要稍后在文件中访问数据,请保存它。如果你需要访问尚未遇到过的东西,你需要一个双程系统,你可以运行一次并存储“第二遍你需要的东西,然后再次运行”。

编译器以这种方式工作。

一次加载整个阵列的唯一情况是,您必须重复随机访问整个阵列中的许多位置。如果是这种情况,我建议你将它加载到多个字节数组中,这些数组都存储在一个容器类中。

容器类将具有一个字节数组数组,但从外部所有访问看起来都是连续的。你只需要字节49874329128714391837,你的类将你的Long除以每个字节数组的大小来计算要访问的数组,然后使用余数来确定字节。

它还可以有方法来存储和检索可能需要创建临时副本的字节数组边界的“块” - 但是创建一些临时数组的成本将超过事实所弥补的成本。您没有分配锁定的2gb空间,我认为这可能会破坏您的性能。

编辑:ps。如果你真的需要随机访问而不能使用流,那么实现一个包含类就是一个非常好的主意。它允许您将实现的实现从单字节数组更改为一组字节数组到基于文件的系统,而不会对其余代码进行任何更改。

答案 3 :(得分:1)

这不是直接的帮助,但是创建具有更大尺寸的数组(通过longs)是Java 7的建议语言更改。查看Project Coin提议以获取更多信息

答案 4 :(得分:0)

“存储”数组的一种方法是将其写入文件,然后使用RandomAccessFile访问它(如果需要像数组一样访问它)。该文件的api使用long作为文件的索引而不是int。它会慢一点,但记忆力要小得多。

这是在初始输入扫描期间无法提取所需内容的时候。