5

ByteArrayOutputStreamオブジェクトがあり、次のエラーが発生します。

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

250mbのbyte[]チャンクを一度に1つずつ書き込むことにより、複数のギグのファイルをロードしようとしています。

バイトのサイズが大きくなるのを見ることができ、intの上限である長さ2147483647に達するとすぐに、次の行で爆発します。

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 でなければなりません。そうしないと、コンパイル時エラーが発生します。これは、具体的には、ディメンション式の型が long であってはならないことを意味します。

同様に、arraylength の JVM 仕様では次のようになります。

arrayref は型参照である必要があり、配列を参照する必要があります。オペランド スタックからポップされます。参照する配列の長さが決定されます。その長さは int としてオペランド スタックにプッシュされます

これは基本的に、配列の最大サイズを強制します。

データをロードした後に何をするつもりだったのかは明確ではありませんが、最初からすべてをメモリにロードする必要はないようにします。

于 2012-02-22T15:19:44.737 に答える
2

ByteArrayOutputStreamを使用して数GiBのデータを書き込むことは、すべてがコンピューターのメモリに保持されている必要があるため、お勧めできません。お気づきのとおり、バイト配列は2 ^ 31バイト(2GiB)に制限されています。

さらに、そのデータを格納するために使用されるバッファーは、さらにデータを書き込んでも大きくなりません。したがって、使用されるバッファーがいっぱいになると、新しいバッファーを作成し(通常は2倍のサイズ)、すべてのデータを古いバッファーからコピーする必要があります。新しいものに。

私のアドバイスは、RandomAccessFileを使用して、取得したデータをファイルに保存することです。RandomAccessFileを介して、2GiBより大きいデータファイルを操作できます。

于 2012-02-22T15:30:29.047 に答える
2

複数の配列を使用します。制限に達したらByteArrayOutputStream.toByteArray()、 でリセットしByteArrayOutputStream.reset()ます。

于 2012-02-22T15:20:57.753 に答える