2009-09-08 8 views
12

はこれです:あらかじめ割り当てるバイト数がわからない場合は、ByteBufferを初期化する方法はありますか?

ByteBuffer buf = ByteBuffer.allocate(1000); 

... ByteBufferを初期化する唯一の方法は?

割り振る必要のあるバイト数がわからない場合はどうすればいいですか?

編集:詳細:

私は、TIFFファイルに1つの画像ファイル形式を変換しています。問題は、開始ファイルの形式は任意のサイズにすることができますが、TIFF形式のデータをリトルエンディアンに書き込む必要があります。だから私は最終的にByteBufferにTIFFファイルに印刷するものを読んでいるので、すべてをLitt​​le Endianに入れてから、outfileに書き込むつもりです。私は、IFDがどれくらいの長さでヘッダがあるかを知っているので、各画像プレーンのバイト数を調べることができます。このプロセス全体で複数のByteBuffersを使用できます。

答えて

7

依存します。ファイル形式を変換する

ライブラリ

は、ほとんどの問題領域のために解決される問題である傾向があります。たとえば、

  • Batikさまざまな画像形式(TIFFを含む)でトランスコードすることができます。
  • Apache POIは、オフィススプレッドシート形式の間で変換できます。
  • FlexmarkはMarkdownからHTMLを生成できます。

リストが長いです。最初の質問は、 "libraryはこのタスクを達成できますか?"パフォーマンスが考慮されている場合は、別のツールを作成するよりも、ニーズに合わせて既存のパッケージを最適化するのに時間がかかる可能性が高くなります。 (ボーナスとして、他の人たちは、集中作業の恩恵を受けることを得る。)


既知量のファイルを読み込み

  • file.size()バイトを割り当てます。
  • 文字列をコピーしますか? string.length()バイトを割り当てます。
  • TCPパケットをコピーしていますか?たとえば、1500バイトを割り当てます。

未知数バイト数が本当に未知の場合、あなたはいくつかのことを行うことができます

  • 推測してください。
  • サンプルデータセットをバッファに解析します。平均の長さを使用してください。

JavaのStringBuffer、特に指示がない限り、16個の文字を保持するために、最初のバッファサイズを使用しています。 16文字が一度満たされると、新しいより長い配列が割り当てられ、元の16文字がコピーされます。 StringBufferの初期サイズが1024文字の場合、再割り当ては早くも頻繁にも行われません。

最適化

いずれにせよ、これはおそらく時期尚早の最適化です。通常、実行される内部メモリの再割り当ての数を減らしたい場合は、設定されたバイト数を割り当てます。

これがアプリケーションのボトルネックになる可能性は低いです。

+3

' StringBuffer'は動作が異なります。 'ByteBuffer'は、さらに追加しようとすると' BufferOverflowException'をスローします。 – bvdb

4

考えているのは、バッファーで、データ全体ではないということです。チャンクを読んだり、処理したり(おそらく別の場所に書き込んでいる)、データを一時的に休止する場所です。だから、自分自身に十分な大きさのチャンクを割り当ててください。通常は問題にはなりません。

あなたはどんな問題を予期していますか?

10

ByteBufferを使用する場所のタイプは、通常、バイト配列(固定サイズもあります)を使用する場所の種類です。同期I/Oでは、バイト配列を非同期I/Oで使用することがよくありますが、ByteBuffersが代わりに使用されます。

あなたは、ByteBufferを使用してデータの未知の量を読んで、あなたの緩衝液でループの使用を検討し、あなたがそれを読むようByteArrayOutputStreamにデータを追加する必要がある場合。終了したら、toByteArray()に電話して、最後のバイト配列を取得します。

入力のサイズ(または最大サイズ)が絶対にわからない場合は、ループで読み込みます(おそらくByteArrayOutputStreamを使用しますが、それ以外の場合はストリームとして処理します)。 )これを処理する唯一の方法です。何らかのループがなければ、残りのデータはもちろん失われます。例えば

:あなたの代わりにJavaのint S、または生のバイトではない他のものを書きたい場合は

final byte[] buf = new byte[4096]; 
int numRead; 

// Use try-with-resources to auto-close streams. 
try(
    final FileInputStream fis = new FileInputStream(...); 
    final ByteArrayOutputStream baos = new ByteArrayOutputStream() 
) { 
    while ((numRead = fis.read(buf)) > 0) { 
    baos.write(buf, 0, numRead); 
    } 

    final byte[] allBytes = baos.toByteArray(); 

    // Do something with the data. 
} 
catch(final Exception e) { 
    // Do something on failure... 
} 

、あなたがDataOutputStreamであなたのByteArrayOutputStreamをラップすることができます

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
DataOutputStream dos = new DataOutputStream(baos); 

while (thereAreMoreIntsFromSomewhere()) { 
    int someInt = getIntFromSomewhere(); 
    dos.writeInt(someInt); 
} 

byte[] allBytes = baos.toByteArray();  
+0

ByteArrayOutputStreamを使用してこの例を挙げることはできますか?整数を言うとしましょうか? –

+0

@PaulaKristin今すぐチェックしてください(壊れた 'ByteArrayOutputStream'リンクも修正しました) –