28

サイズがタイプのバイト配列を作成しようとしていますlong。たとえば、次のように考えてください。

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

intどうやら、バイト配列のサイズに対してのみを指定できます。

なぜこんなに大きなバイト配列が必要なのかと誰かが尋ねる前に、私が書いていないメッセージ形式のデータをカプセル化する必要があると言います。これらのメッセージタイプの1つはunsigned int(longJavaの場合)の長さです。

このバイト配列を作成する方法はありますか?

それを回避する方法がない場合は、バイト配列の出力ストリームを作成してバイトを送り続けることができると思いますが、バイト配列のサイズに制限があるかどうかはわかりません...

4

5 に答える 5

26

(OPにはおそらく少し遅れますが、それでも他の人には役立つかもしれません)

残念ながら、Javaは231-1を超える要素を持つ配列をサポートしていません。最大消費量は、アレイの場合は2 GiBのスペース、byte[]アレイの場合は16GiBのスペースですlong[]

この場合はおそらく適用できませんが、配列がスパースになる場合は、のような連想データ構造を使用して、Map使用されている各オフセットを適切な値に一致させることができる場合があります。さらに、Troveは、標準のJavaコレクションよりもプリミティブ値を格納するためのよりメモリ効率の高い実装を提供します。

配列がスパースではなく、実際にメモリ内のBLOB全体が必要な場合は、おそらく2次元構造を使用する必要があります。たとえば、Map1024を法として適切な1024バイト配列にオフセットを一致させる必要があります。Mapこのアプローチは、隣接する塗りつぶされたセルが同じエントリを共有できるため、スパース配列の場合でもメモリ効率が高くなる可能性があります。

于 2012-05-28T15:40:03.303 に答える
7

byte[]最大 32 ビット符号付き整数のサイズの には、2GB の連続したアドレス空間が必要です。そのような配列を作成しようとしないでください。それ以外の場合、サイズが実際にはそれほど大きくない場合 (および型が大きいだけの場合) は、安全に にキャストし、intそれを使用して配列を作成できます。

于 2009-07-01T23:50:48.073 に答える
1

おそらく、ストリームを使用してデータを読み込み、別のストリームを使用してデータを書き出す必要があります。後でファイル内のデータにアクセスする必要がある場合は、ファイルを保存してください。まだ遭遇していないものにアクセスする必要がある場合は、1 回実行して「2 回目のパスに必要なものを保存してから、もう一度実行する」という 2 パス システムが必要です。

コンパイラはこのように動作します。

一度に配列全体をロードする唯一のケースは、配列全体の多くの場所に繰り返しランダムにアクセスする必要がある場合です。このような場合は、単一のコンテナ クラスにすべて格納されている複数のバイト配列にロードすることをお勧めします。

コンテナー クラスにはバイト配列の配列がありますが、外部からはすべてのアクセスが連続しているように見えます。バイト 49874329128714391837 を要求するだけで、クラスは Long を各バイト配列のサイズで割り、アクセスする配列を計算し、残りを使用してバイトを決定します。

また、一時コピーを作成する必要があるバイト配列境界にまたがる可能性のある「チャンク」を格納および取得するメソッドを持つこともできますが、いくつかの一時配列を作成するコストは、ロックされた2GBのスペースが割り当てられていないため、パフォーマンスが低下する可能性があります。

編集:ps。本当にランダムアクセスが必要で、ストリームを使用できない場合は、包含クラスを実装することは非常に良いアイデアです。これにより、コードの残りの部分を変更することなく、実装を単一のバイト配列からバイト配列のグループ、ファイルベースのシステムにその場で変更できます。

于 2009-07-02T00:13:57.903 に答える
1

すぐには役に立ちませんが、より大きなサイズの配列を (long を介して) 作成することは、Java 7 で提案されている言語変更です。詳細については、Project Coin の提案を確認してください。

于 2009-07-02T10:24:57.563 に答える
0

配列を「格納」する 1 つの方法は、ファイルに書き込んでから (配列のようにアクセスする必要がある場合)、RandomAccessFile を使用してアクセスすることです。そのファイルの API は、ファイルへのインデックスとして int ではなく long を使用します。遅くなりますが、メモリへの負担ははるかに少なくなります。

これは、最初の入力スキャン中に必要なものを抽出できない場合です。

于 2009-07-02T00:35:09.513 に答える