2012-02-24 11 views
0

私は、クライアントからのPOSTとしてログファイルに書き込むプロセス(実際にはWebサーバー)を持っています。行が完了する前にBufferedReader readLine

それから私は、ループ内で(テール-f)のようなログファイルを読み込み、別のプロセスがあります。

  BufferedReader reader = new BufferedReader(new FileReader(logFilePath)); 
      String line = null; 

      while (true) 
      { 
        if ((line = reader.readLine()) != null) 
        { 
          if (firstLine == null) firstLine = line; 
          processLine(line); 
          continue; 
        } 

        try 
        { 
          Thread.sleep(sleepTime); 
          long ts = System.currentTimeMillis(); 
        } catch (InterruptedException e) { 
          Thread.currentThread().interrupt(); 
          break; 
        } 
      } 

これは、時折非常によく、時間の99%を働くが、私はで読み込まラインをBufferedReader.readLineは完全な行ではありません。私は、ライター(Webサーバー)がファイルの行のすべてのバイトをまだフラッシュし終えていないためだと思います。

この問題を修正または回避するには、どうもありがとう!

+0

行が完了していないときに検出するパターンはありますか? – VirtualTroll

+0

ちょっとしたポインタ: 'while(true)... break'を使う必要はありません。続けるべきかどうかを変数で調べることができます。 – Viruzzo

+0

これはあなたを助けるかもしれないと思います: http://docs.oracle.com/javase/1.4.2/docs/api/java/io/FileDescriptor.html#sync() – nullpotent

答えて

1

1つのファイルにほぼ同時にアクセスする必要のある複数のプロセス(多くの場合、すぐ後で1つのプロセス)で作業していたので、(私が協力してくれた他の開発者と共に)あるプロセスが他のプロセスがアクセスする必要のあるファイルと対話するタイミングを示すために使用するとよいでしょう。

あなたのウェブサーバがこのログに書き込む頻度と、あなたのJavaプロセスがそれを読むのにどれくらいの時間がかかるかはよく分かりませんが、各プロセスがファイルにアクセスするまでに時間がかかる場合は、あなたのウェブサーバーがいつファイルに書き込まれたかを示す書き出されます。 Javaプロセスは、まずトレーラファイルが存在するかどうかを確認し、それが見つかったらログを削除してから読み込むことができます。

OSコマンドを使用して、Webサーバーがログに書き込んでいるかどうかを調べ、そうでないときはログリーダーを実行する必要があります。 http://blog.bensmann.com/executing-operating-system-commandsには、JavaでOSコマンドを実行すると良い情報があります。

ボトムラインは、これらのプロセスがログに同時に読み書きしないように確立されたソートが必要です。

+0

おかげでザック。ウェブサーバーはかなり速く、毎秒kBの回線とcouleを書き込み、それは成長しています。ウェブサーバーの書き込みが完了しているかどうかをチェックするのは高額になるかどうかはわかりません。 私は実際にそれが役立つが、それを行う方法がわからない場合は、読者が少し後ろになって気にしない。 –

-1

私は最近、同じ問題に直面しました。いつbufferreaderがreadline() メソッドで不完全な行を読み上げるかを説明しましょう。これは、キャリッジリターンの前にEOFが発生したときに実行されます。

BufferedReaderのをreadineのコードは、それがキャリッジの前にEOFが発生した場合、それはそれはすでに読んでいるものは何でも返します返すことを言います。この

if (nextChar >= nChars) 
        fill(); 
       if (nextChar >= nChars) { /* EOF */ 
        if (s != null && s.length() > 0) 
         return s.toString(); 

        else 
         return null; 
       } 

のようなものです。 しかし、正しいコードはreadLine()を呼び出すときで、EOF文字がキャリッジretunnの前に見つかると、不完全な行の代わりにNULLが返されます。

上記のシナリオでReadLineがNULLを返す拡張bufferedreaderクラスを作成しました。

+1

「EOFキャラクター」とは何ですか? –

+0

EOF文字について引用したコードには何もありません。 EOF文字はありません。 EOF *条件があります。* – EJP

関連する問題