28

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

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

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

在有人问我为什么需要这么大的字节数组之前,我会说我需要封装我不写的消息格式的数据,其中一种消息类型的长度是无符号整数(long在 Java 中)。

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

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

4

5 回答 5

26

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

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

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

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

于 2012-05-28T15:40:03.303 回答
7

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

于 2009-07-01T23:50:48.073 回答
1

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

编译器以这种方式工作。

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

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

它还可以具有存储和检索可能跨越字节数组边界的“块”的方法,这需要创建一个临时副本——但是创建一些临时数组的成本将远远超过你不这样做的事实没有分配锁定的 2gb 空间,我认为这只会破坏你的表现。

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

于 2009-07-02T00:13:57.903 回答
1

它不是立竿见影的帮助,但创建更大尺寸的数组(通过 longs)是 Java 7 的一项提议的语言更改。查看 Project Coin 提案以获取更多信息

于 2009-07-02T10:24:57.563 回答
0

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

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

于 2009-07-02T00:35:09.513 回答