2017-12-25 12 views
1

他のアプリケーション/プロセスによって積極的に書き込まれているファイルから読み込みたいです。Javaを使用して積極的に書き込まれているファイルから読み込み[改善]

私が別の質問で見つけたこのコードは、仕事をしています:ファイルが書き込まれている間にそのファイルを読み取り、新しいコンテンツのみを読み込みます。

ファイルにデータが追加されていなくても、多くのCPUを消費するという問題。このコードをどのように最適化できますか?

  • タイマーを使用しますか?またはthread.sleepを一時停止するには?

追加するもう1つのことは、書き込みしようとしているプログラム全体がファイルをリアルタイムで読み取り、その内容を処理することです。だから、これはthread.sleepかタイマーが私の全プログラムを一時停止することを意味します。私が探している理想的な改善は数秒待つことではなく、特定のイベントが発生するためです。>新しいデータが追加されます。これは可能ですか?

public class FileReader { 
 

 
    public static void main(String args[]) throws Exception { 
 
     if(args.length>0){ 
 
      File file = new File(args[0]); 
 
      System.out.println(file.getAbsolutePath()); 
 
      if(file.exists() && file.canRead()){ 
 
       long fileLength = file.length(); 
 
       readFile(file,0L); 
 
       while(true){ 
 

 
        if(fileLength<file.length()){ 
 
         readFile(file,fileLength); 
 
         fileLength=file.length(); 
 
        } 
 
       } 
 
      } 
 
     }else{ 
 
      System.out.println("no file to read"); 
 
     } 
 
    } 
 

 
    public static void readFile(File file,Long fileLength) throws IOException { 
 
     String line = null; 
 

 
     BufferedReader in = new BufferedReader(new java.io.FileReader(file)); 
 
     in.skip(fileLength); 
 
     while((line = in.readLine()) != null) 
 
     { 
 
      System.out.println(line); 
 
     } 
 
     in.close(); 
 
    } 
 
}

答えて

1

私が探しています理想的な改善は、数秒待つことではなく、起こるために、特定のイベントのための は=>新しいデータが追加されます。これは可能ですか?

ベスト液:プッシュデータ:

それがコンテンツを読み取ることができるように、コンテンツは、他のアプリケーションに通知する必要があり生産アプリケーション。

2つの異なるアプリケーション間で情報を伝えるチャネルを使用できます。

たとえば、ライターが更新する特定のファイルを使用して、新しいものを読み取るように通知します。
ライターは、このファイルに更新日を書き込んだり上書きしたりすることができ、この日付以降に内容を読み取らない場合にのみリーダーはデータファイルを読み込みます。

より堅牢な方法ですが、オーバーヘッドが増えると、リーダ側から通知サービスが公開される可能性があります。
なぜRESTサービスではないですか?
このようにして、ライターは、新しいコンテンツが準備されているので、サービスを介してリーダーに通知することができます。

追加するもう一つは、私が記述しようとしています全体のプログラムは、リアルタイムで ファイルを読み込み、その内容を処理します。これはつまり、 thread.sleepを意味するか、タイマーは私のプログラム全体を一時停止します。

回避策ソリューション:あなたはおそらく、マルチコアCPUを持って

:特定のスレッドによって行わ引っ張ったデータ。
別のスレッドを作成して、生成されたファイルを読み込んで、アプリケーションの他のスレッドを実行可能にします。
さらに、定期的なポーズを行うこともできます:Thread.sleep()読み取りスレッドによって行われるコアの使用を最適化します。 MyReadingProcessingRunnableある

Thread readingThread = new Thread(new MyReadingProcessing()); 
readingThread.start(); 

:それは次のようになり

public class MyReadingProcessing implements Runnable{ 

    public void run(){ 
      while (true){ 
       readFile(...); 
       try{ 
        Thread.sleep(1000); // 1 second here but choose the deemed reasonable time according the metrics of your producer application 
       } 
       catch(InterruptedException e){ 
        Thread.currentThread().interrupt(); 
       } 
       if (isAllReadFile()){ // condition to stop the reading process 
        return; 
       } 
      } 
    } 
} 
+0

ありがとうございます。私は2つのアプリケーションに焦点を当てようとはしていません。 前述のとおり、上記のコードは通知を送信することでジョブを実行します。私が解決しようとしている問題は、スレッドが決して一時停止しないため、アプリケーションのオーバーヘッドを減らすことです。 –

+0

ようこそ。わかりました。私は更新しました。それが有用かどうか見てみましょう – davidxxx

+0

あなたの答えをありがとう:)。 –

0

代わりに忙しい待ちループのは、変化するディレクトリエントリにWatchServiceを使用しています。

上記は、pollまたはtakeを使用するように適合されなければならないことに注意してください。

関連する問題