web-dev-qa-db-ja.com

Javaサイズがlongで表されるバイト配列を作成する

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

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

どうやら、バイト配列のサイズに指定できるのはintだけです。

なぜバイト配列がこんなに大きい必要があるのか​​と尋ねる前に、私が書いていないメッセージフォーマットのデータをカプセル化する必要があると言います。これらのメッセージタイプの1つは、unsigned int(long Javaで)。

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

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

26
jbu

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

6
Mehrdad Afshari

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

コンパイラはこのように機能します。

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

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

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

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

1
Bill K

これはすぐには役に立ちませんが、(longsを介して)より大きなサイズの配列を作成することは、Java 7。

1
Brian Agnew

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

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

0
Kathy Van Stone