web-dev-qa-db-ja.com

Javaテキストファイルの先頭に戻るBufferedReader?

現在、同じテキストファイルで2つのBufferedReadersが初期化されています。最初のBufferedReaderでテキストファイルの読み取りが完了したら、2番目のテキストファイルを使用して、ファイルの先頭から別のパスを作成します。同じファイルを複数回パスする必要があります。

私はreset()について知っていますが、mark()mark()を呼び出す前にファイルのサイズを知る必要があります。気にする必要があります。

アイデア?パッケージ? Libs?コード?

ありがとうTJ

26
T to the J

新しいBufferedReaderを作成して上から読むだけの短所は何ですか?ファイルが十分に小さい場合、オペレーティングシステムがファイルをキャッシュすることを期待します。

パフォーマンスに懸念がある場合、それがボトルネックであることを証明しましたか?私は最も単純なことをするだけで、特定の理由があるまで心配しないでください。つまり、すべてをメモリに読み込んで、結果に対して2つのパスを実行することもできますが、新しいリーダーを使用して最初から読み直すよりも複雑になります。

25
Jon Skeet

バッファーリーダーは、ファイルを順番に読み取るためのものです。探しているのは Java.io.RandomAccessFile で、seek()を使用してファイル内の目的の場所に移動できます。

ランダムアクセスリーダーは次のように実装されます。

try{
     String fileName = "c:/myraffile.txt";
     File file = new File(fileName);
     RandomAccessFile raf = new RandomAccessFile(file, "rw");
     raf.readChar();
     raf.seek(0);
} catch (FileNotFoundException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
} catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
}

"rw"はモード文字で、 詳細はこちら です。

シーケンシャルアクセスリーダーがこのように設定されている理由は、バッファーを実装でき、物事を足元で変更できないようにするためです。たとえば、バッファリーダーに与えられるファイルリーダーは、そのバッファリーダーによってのみ操作される必要があります。影響を与える可能性のある別の場所がある場合、一方のリーダーがファイルリーダー内でその位置を進めたときに、他方のリーダーが同じ場所に留まるようにしたため、他のリーダーを使用して不定の場所にあるため、一貫性のない動作が発生する可能性があります。

29
Ryan P

続行する最善の方法は、2回目のパスが不要な方法でアルゴリズムを変更することです。私はこのアプローチを数回使用しましたが、使用可能なメモリに収まらない巨大な(ひどい、つまり数GB)ファイルを処理する必要がありました。

それは難しいかもしれませんが、パフォーマンスの向上は通常努力する価値があります

3
Davide

マーク/リセットについて:

BufferedReaderのmarkメソッドはreadAheadLimitパラメーターを取ります。このパラメーターは、マークがリセットされてから不可能になるまでの読み取り範囲を制限します。リセットは、実際にはファイルシステムのseek(0)を意味するのではなく、バッファ内をシークするだけです。 Javadocを引用するには:

readAheadLimit-マークを保持したまま読み取ることができる文字数の制限。この数の文字を読み取った後、ストリームをリセットしようとすると失敗する場合があります。入力バッファのサイズよりも大きい制限値は、サイズが制限以上の新しいバッファを割り当てます。したがって、大きな値は注意して使用する必要があります。

1
Zarkonnen