java byte生成文件大小_Java创建字节数组,其大小用long表示

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

long x = _________;

byte[] b = new byte[x];

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

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

有没有办法创建此字节数组?

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

大多数32位体系结构上的unsigned int仅比Java中的int多一位。 Java long为64位,不适用于数组索引。

我意识到这一点,但是我不知道在不实现自己的数据类型的情况下完全表示消息指定的数据量的方法。

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

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

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

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

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

最初的提问者大概没有使用32位JVM。具有2 ^ 32个字节的int []数组是可构造的...

实际上,因为Java类型是带符号的,所以最大值是31位整数。因此大约2个演出。

jbu:糟糕。你是对的。显然,它也可以在64位进程中使用,但是我想说的是它太大了,如果您真的要创建这么大的数组,那么您很可能走错了路。

mehrdad:我不知道Im是否走错了……再次,我处理的消息类型可能很大(理论上)。似乎走错路的是创建此消息类型的人。我不知道他是否使用了消息的全部大小,但是我想我想支持他的消息并且不丢弃字节(即使他使用了它们)。

如果您真的希望消息那么大,则应使用某种缓冲机制,以免将整个事件立即加载到内存中。我只是尝试在64位JVM中创建2 ^ 30字节(Integer.MAX_VALUE / 2)的数组,它抛出OutOfMemoryError。

是的,我相信它是...堆栈溢出:)我想我需要扔掉字节,或者问这个人是否打算使用所有这些字节。

jbu:实际上,它不是在堆栈上创建的。它缺少足够的Java堆空间。我可以在64位上创建Integer.MAX_VALUE / 4个字节,而在32位上创建得多(几乎没有)。如果您希望消息大于几百兆字节,则应该考虑一下缓冲。

作为拥有32GB内存的计算机的人,我看不到分配2GB连续内存的问题。...最终,这将是需要更改的人为限制。

它并不能立即提供帮助,但是创建较大尺寸的数组(通过long数组)是Java 7的一种建议语言更改。有关更多信息,请查看Project Coin建议。

参考:blogs.oracle.com/darcy/entry/project_coin_consideration_round_2; mail.openjdk.java.net/pipermail/coin-dev/2009-March/000869.html

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

编译器以这种方式工作。

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

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

它还可能具有存储和检索可能跨越字节数组边界的"块"的方法,这需要创建一个临时副本,但是创建一些临时数组的成本将因您不这样做而弥补。我没有分配锁定的2gb空间,我认为这只会破坏您的性能。

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

我怀疑即使在这种情况下,您是否也可以分配这么多的内存。更不用说long了,第二行在我的计算机上的64位JRE上引发异常:" byte [] a1 =新的byte [Integer.MAX_VALUE / 4]; byte [] a2 =新的字节[Integer.MAX_VALUE / 4] ;"如果要处理大量数据,他将不得不使用某种类型的内存缓冲区。

这就是为什么我建议了一个小类,可以用来即时更改实现。当然,应尽可能使用流传输(并且绝对应该可以!),如果不能,则可以使用某种缓存算法,其中软引用保存的块较小。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值