8

私は、多くの I/O を実行する必要がある非常に高速な Java コードを作成しようとしています。ByteBuffer を返すメモリ マップ ファイルを使用しています。

public static ByteBuffer byteBufferForFile(String fname){
    FileChannel vectorChannel;
    ByteBuffer vector;
    try {
        vectorChannel = new FileInputStream(fname).getChannel();
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
        return null;
    }
    try {
        vector = vectorChannel.map(MapMode.READ_ONLY,0,vectorChannel.size());
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    return vector;
}

私が抱えている問題は、ByteBuffer .array() メソッド (byte[] 配列を返す必要がある) が読み取り専用ファイルに対して機能しないことです。メモリ内に構築されたメモリ バッファとディスクから読み取られたバッファの両方で動作するようにコードを記述したいと考えています。しかし、すべてのバッファを ByteBuffer.wrap() 関数でラップしたくありません。これにより速度が低下するのではないかと心配しているからです。そのため、私はすべての 2 つのバージョンを作成しました。1 つは byte[] を受け取り、もう 1 つは ByteBuffer を受け取ります。

私はすべてをラップする必要がありますか?それとも、すべて二重に書くべきですか?

4

4 に答える 4

10

読み取り専用/読み取り書き込みに関係なく、最初にByteBuffersメモリマッピングサポートの呼び出しによって作成されたかどうかを実際に確認した人はいますか?.array()

私の知る限り、答えはNOです。ByteBufferを介して直接byte[]配列を返すAの機能は、 ( )ByteBuffer.array()の存在によって制御されます。これは、 a の作成時に常に null に設定されます。ByteBuffer.hbbyte[]MappedByteBuffer

質問の作者がやりたかったことと似たようなことをしたいと思っていたので、これはちょっと残念です。

于 2009-07-15T20:27:25.610 に答える
7

車輪を再発明しないことは常に良いことです。Apache は、I/O 操作を実行するための美しいライブラリを提供しています。http://commons.apache.org/io/description.htmlを ご覧ください。

これが提供するシナリオです。メモリに保持したいデータがいくつかあるが、どれだけのデータが存在するかは前もってわからないとします。容量が多すぎる場合は、メモリを占有するのではなくディスクに書き込みますが、ディスクは低速であり、クリーンアップのために追跡が必要なリソースであるため、必要になるまでディスクに書き込みたくありません。

したがって、一時バッファを作成し、そこへの書き込みを開始します。メモリに保持したいもののしきい値に達した場合は、ファイルを作成し、バッファにあるものをそのファイルに書き出し、後続のすべてのデータをバッファではなくファイルに書き込む必要があります。

それがDeferredOutputStreamが行うことです。切り替え時の混乱をすべて隠します。最初に遅延ストリームを作成し、しきい値を構成してから、心ゆくまで書き込むだけです。

編集: Google を使用して小さな再検索を行ったところ、次のリンクが見つかりました: http://lists.apple.com/archives/java-dev/2004/Apr/msg00086.html (Lightning fast file read/write)。非常に印象的。

于 2009-06-21T06:31:23.490 に答える
4

byte[] をラップしても速度が低下することはありません...巨大な配列のコピーやその他の小さなパフォーマンスの悪はありません。JavaDocsから: java.nio.ByteBuffer .wrap()

バイト配列をバッファーにラップします。

新しいバッファは、指定されたバイト配列によってサポートされます。つまり、バッファを変更すると配列が変更され、その逆も同様です。新しいバッファの容量と制限は array.length になり、その位置はゼロになり、そのマークは未定義になります。そのバッキング配列は指定された配列になり、その配列オフセットはゼロになります。

于 2009-06-21T06:08:00.073 に答える
1

ByteBuffer.wrap() 機能を使用しても、大きな負荷はかかりません。単純なオブジェクトを割り当て、いくつかの整数を初期化します。したがって、読み取り専用ファイルを操作する必要がある場合は、ByteBuffer に対してアルゴリズムを記述することが最善の策です。

于 2009-06-21T06:04:44.200 に答える