9

私が持っているタスクは、非常に大きく、継続的に成長しているファイルを (ある程度効率的に) 1 行ずつ読み取ることです。基本的に私が今やっていることは次のとおりです。

BufferedReader rd = //initialize BufferedReader
String line;
while(true){
    while((line=rd.readLine())==null){
        try{
            Thread.sleep(1000);
        }catch(InterruptedException e){
            //handle exception
        }
    }
    //process line
}

したがって、私の BufferedReader は、読み取るものがさらにあるまで、ファイルの最後でハングします。これはうまく機能しますが、1 つ問題があります。ファイルに書き込むプロセスが行を書き込んでいる最中に readLine が呼び出された場合です。次に、readLine の最初の呼び出しで行の最初のセクションが返され、次の呼び出しで 2 番目のセクションが返されます。しかし、私は本当にこれら 2 つの部分を一緒にする必要があります。完全なセリフが必要です。

より具体的には、次のイベントのインターリーブが発生したときに問題が発生します。

  1. 書き込みプロセスはほとんどの行を書き込みます
  2. readLine() が呼び出されます
  3. 書き込みプロセスはその行を終了し、改行文字を追加します
  4. readLine() が呼び出されます

その結果、各 readLine() は、書き込みプロセスが出力している行全体のセクションを取得します。呼び出されるたびにファイルの最後に到達し、読み取ったものを返すため、期待どおりに動作しています。

したがって、基本的に必要な機能は、readLine の 1 つ前に null を返す BufferedReader です。EOFだけでなく、改行が続くまで行を提供しないもの。したがって、EOF が見つかった場合、その時点までの行は返されず、null が返され、ファイルが書き込まれ、その後に新しい行があると、その行が返されます。

FileReader をより直接的に処理し、本質的に BufferedReader を書き直すことで、おそらくこれを行う大まかな方法​​を実装できますが、これを効率的に行う方法についてはあまり知りません。私の実装はおそらく実際の BufferedReader ほど高速ではなく、読み取るデータがあるときにプログラムの速度が低下するのを避けたいと考えています。

4

5 に答える 5

2

BufferedReader のソースから始めて String readLine(boolean ignoreLF)、行末の前に EOF が見つかった場合に問題を引き起こすメソッドを書き直すことができます。(残念ながらパッケージスコープの関係で継承できません)

于 2010-07-08T17:21:59.350 に答える
1

BufferedReaderストリームの最終的な最後に到達するまで null を返すことは意図されていません。つまり、null が返された後、null 以外が返されることはないと思います。

ただし、部分的な行が表示されることに少し驚いています。行全体が表示されるまでブロックされると思います。

于 2010-07-08T17:09:45.680 に答える
0

http://www.gnu.org/software/kawa/api/gnu/text/LineBufferedReader.htmlを試す
ことができます。これにより、行の先頭に戻ることができます

于 2010-07-08T17:08:53.523 に答える
0

stacker が言ったように、最善の方法は Bufferedreader を継承するクラスを構築することです。私が見つけたのは、BufferedReader が EOF に達したときです。読み続けたい場合、または新しいものがあるかどうかを確認したい場合は、いつでも再開してスキップできます。実際には、スキップする場所が正確にわかっていれば、それほど時間はかかりません。この質問の答えを見てください。彼は、リーダーに reloadat() 関数を作成して、リーダーがリフレッシュされるようにしました。

ファイルの最後まで読み取った後、BufferedReader のリセットが失敗する

于 2014-07-08T21:08:59.323 に答える
0

プッシュバック リーダーを使用して、常に最後の行を押し戻すようにしてください。

于 2010-07-08T17:23:30.403 に答える