26

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

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

アイデア?パッケージ?図書館?コード?

ありがとうTJ

4

5 に答える 5

29

バッファリーダーは、ファイルを順番に読み取ることを目的としています。探しているのは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"ているモード キャラクタです。

シーケンシャル アクセス リーダーがこのように設定されている理由は、バッファーを実装し、足元で変更できないようにするためです。たとえば、バッファリングされたリーダーに与えられたファイルリーダーは、そのバッファリングされたリーダーによってのみ操作されるべきです。それに影響を与える可能性のある別の場所があった場合、1 つのリーダーがファイル リーダー内でその位置を進めたのに対し、もう 1 つのリーダーは同じ位置を維持したかったため、別のリーダーを使用し、その場所が未定になったため、操作に一貫性がなくなる可能性があります。

于 2008-11-04T17:55:23.483 に答える
26

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

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

于 2008-11-04T17:35:53.167 に答える
3

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

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

于 2008-11-04T17:56:15.323 に答える
1

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

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

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

于 2008-11-05T12:48:52.730 に答える
-1

「BufferedReader の mark() と reset() に関するビジネス全体が、設計の悪さを感じさせます。」

このクラスを拡張して、constructor() で mark() を実行してから、topOfFile() メソッドで seek(0) を実行してみませんか。

BR、
~A

于 2008-11-04T20:05:27.747 に答える