5

我有一个 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 上限的字节数组大小吗?

4

3 回答 3

8

Java 中的数组根本不能超出int.

JLS 第 15.10 节

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

同样在JVM 规范中的 arraylength

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

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

目前还不清楚加载数据后您将如何处理数据,但我会尝试不需要将其全部加载到内存中。

于 2012-02-22T15:19:44.737 回答
2

使用多个数组。当您达到限制使用ByteArrayOutputStream.toByteArray()并重置时ByteArrayOutputStream.reset()

于 2012-02-22T15:20:57.753 回答
2

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

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

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

于 2012-02-22T15:30:29.047 回答