超过byte []数组长度(超过int上限) - java.lang.ArrayIndexOutOfBoundsException

时间:2012-02-22 15:15:17

标签: java byte bytearrayoutputstream

我有一个ByteArrayOutputStream对象,我收到以下错误:

java.lang.ArrayIndexOutOfBoundsException at 
java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:113)

我试图通过一次写一个250mb的byte []块来加载一个几次演出的文件。

我可以看到字节大小增加,一旦达到长度2147483647(int的上限),就会在下一行中爆炸:

stream.write(buf); 

stream是ByteArrayOutputStream,buf是我用250mb块写入流的。

我打算做

byte result[] = stream.toByteArray();

最后。是否有其他方法我可以尝试支持大于int上限的字节数组大小?

3 个答案:

答案 0 :(得分:7)

Java中的数组不能超过int的范围。

来自JLS section 15.10

  

DimExpr中每个维度表达式的类型必须是可转换(第5.1.8节)为整数类型的类型,否则会发生编译时错误。每个表达式都经过一元数字推广(§)。提升类型必须为int,否则会发生编译时错误;具体而言,这意味着维度表达式的类型不能太长。

同样在JVM spec for arraylength

  

arrayref必须是类型引用,并且必须引用数组。它从操作数堆栈中弹出。确定它引用的数组的长度。 该长度作为int 被推送到操作数堆栈。

这基本上强制了数组的最大大小。

在加载数据之后,你不清楚你要对数据做什么,但是我试图不需要将它全部加载到内存中来开始。

答案 1 :(得分:2)

使用多个阵列。达到限制后,使用ByteArrayOutputStream.toByteArray()并使用ByteArrayOutputStream.reset()重置。

答案 2 :(得分:1)

使用ByteArrayOutputStream写入几个GiB数据并不是一个好主意,因为一切都必须保存在计算机的内存中。正如您所注意到的,字节数组限制为2 ^ 31字节(2GiB)。

此外,如果您在其中写入更多数据,用于存储该数据的缓冲区不会增长,因此如果使用的缓冲区已满,则必须创建一个新缓冲区(通常为双倍大小)并且必须从中复制所有数据旧缓冲区进入新缓冲区。

我的建议是使用RandomAccessFile并将您获得的数据保存到文件中。通过RandomAccessFile,您可以对大于2GiB的数据文件进行操作。

相关问题