0

Javaの1つのスレッドでFileInputStreamなどの読み取り呼び出しを行い、2番目のスレッドで同時にロードされているバイトを処理する方法はありますか?私はいくつかのことを試しました-私の現在の試みでは、これを実行しているスレッドが1つあります:

FileChannel inStream;
try {
   inStream = (new FileInputStream(inFile)).getChannel();
} catch (FileNotFoundException e) {
    e.printStackTrace();
}
int result;
try {
     result = inStream.read(inBuffer);
} ...

そして、ロードされているバイトにアクセスしたい2番目のスレッド。明らかに、最初のスレッドでの読み取り呼び出しは、バッファーがいっぱいになるまでブロックされますが、その時点より前にバッファーにロードされたバイトにアクセスできるようにしたいです。現在、私が試したものはすべてバッファがあり、読み取りが完了するまでバッキング配列は変更されていません-これは、このスレッドのポイントを無効にするだけでなく、データがどこかの中間バッファにロードされ、後で私のバッファにコピーされていることを示唆しています。ダフト。

1つのオプションは、配列への小さな読み取りの束を実行し、後続の読み取りでオフセットを使用することですが、これにより余分なオーバーヘッドが追加されます。

何か案は?

4

4 に答える 4

3

データを順番に読み取る場合、OSは必要になる前にデータを先読みします。システムがすでにこれを行っているため、期待するメリットが得られない場合があります。

FilechannelまたはFileInputStreamをByteBufferまたはバイト配列に「フロー」させることができないのはなぜですか?

それはそれがすでに行っていることの一種です。

データをよりシームレスにロードする場合は、メモリマップトファイルを使用して、プログラムのメモリにすぐに「表示」され、使用時にバックグラウンドでロードされます。

于 2012-08-02T20:30:17.160 に答える
1

SynchronousQueueの使用をお勧めします。リーダーはキューからデータを取得し、ライターはファイルからデータを「公開」します。

于 2012-08-02T20:45:21.127 に答える
1

私が通常このような要件で行うことは、複数のバッファクラスインスタンスを使用することです。できれば、効率的なロードを可能にするサイズ(たとえば、クラスタサイズの倍数)を使用します。最初のバッファがロードされるとすぐに、それをキューに入れて(つまり、そのポインタ/インスタンスをプロデューサー/コンシューマーキューにプッシュして)、それを処理するスレッドにキューイングし、すぐに別のバッファーインスタンスを作成(またはデプール)します。その1つをロードし始めます。全体的なデータフローを制御するには、起動時に適切な数のバッファオブジェクトを作成し、それらを「プールキュー」(別の生産者/消費者キュー)に格納してから、データでいっぱいのオブジェクトをプールから次のように循環させることができます。プールに戻るよりも、ファイル読み取りスレッド、次にバッファ処理スレッドに送られます。

これにより、ファイル->処理キューがデータでいっぱいのバッファオブジェクトで「補充」され、一括コピーが不要、避けられない遅延、単一バイトの非効率的なスレッド間通信、バッファインデックスの乱雑なロック、ファイル読み取りスレッドとデータ処理スレッドは、同じバッファーオブジェクトを操作できます。

threadPoolを使用して処理を実行する必要がある場合は、簡単に実行できますが、このサブシステムからの結果の出力を読み取ったときと同じ順序にする必要がある場合は、バッファーオブジェクトにシーケンス番号が必要になることがあります。ファイルから。

buffer-objectsには、結果データメンバー、exception / errorMessageフィールド、その他必要なものが含まれている場合もあります。ファイルや結果データは、再プールされる前に、データ処理(たとえば、ロガーや進行状況のGUI表示)から他のスレッドに簡単に転送できます。それはすべて単なるポインタ/インスタンスのキューイングであるため、大量のデータがシステム内を迅速かつ効率的に流れます。

于 2012-08-02T21:26:20.530 に答える
0

PipedInput / OutputStreamを使用して、見慣れた外観のパイプとバッファーを作成します。

また、必要に応じて、FileInputStreamを使用してバイトごとに読み取ります。fis.read()関数はブロックせず、データがない場合は-1を返し、いつでもavailable()を確認できます。

于 2012-08-02T20:56:01.413 に答える