Javaでは、何が最/安全パターンのための監視中のファイルに追加されますか?

StackOverflow https://stackoverflow.com/questions/1073274

  •  21-08-2019
  •  | 
  •  

質問

ほかの誰かの工程をCSVファイルを追加することによってリトライの間で、イベントが発生します。していませんのファイルのフォーマットやその他のプロセスが知っていまみを追加.

Javaプログラム、モニターは、このファイルがラインが追加されて読み、新しい線に基づいて対応しました。を無視するCSV解析の問題です。には、どうするのがベストな監視するファイルの変化を読み込むためラインです。

理想的にはこの使用の標準ライブラリ。ファイルがこのネットワークドライブというのも何かの固ます。もう少し使用しないでポーリングできればいい。何らかのブロック溶液です。

編集-このブロック解できない標準クラス(たと回答など、最強のポーリング溶液とはなんですか?いと思いませんの再読み込み、全体のファイルの各時間での成長も大きい。

役に立ちましたか?

解決

以来、Java7があり newWatchService() 方法に ファイルシステムクラス.

しかし、注意事項:

  • でJava7
  • このオプションの方法
  • で腕時計のディレクトリにないファイルの取り扱い、自分の中で心配しているファイルの移動など

前のJava7できない標準のApiを用意しています。

また、以下の(ポーリングを1秒間隔で作品(版画処理):

  private static void monitorFile(File file) throws IOException {
    final int POLL_INTERVAL = 1000;
    FileReader reader = new FileReader(file);
    BufferedReader buffered = new BufferedReader(reader);
    try {
      while(true) {
        String line = buffered.readLine();
        if(line == null) {
          // end of file, start polling
          Thread.sleep(POLL_INTERVAL);
        } else {
          System.out.println(line);
        }
      }
    } catch(InterruptedException ex) {
     ex.printStackTrace();
    }
  }

ポリシーにしたがって、かされるソリューションを採用し現在の生産Javaうと思って追加します。に不備があった場合は追加してくださいにコメントです。

他のヒント

あなたはどんな変化がWatchServiceクラスを使用してファイルに発生した場合、ファイルシステムによって通知を受けるように登録することができます。これは、Java7、ドキュメントはこちらのリンクを必要と http://docs.oracle .COM /のJava SE /チュートリアル/不可欠/ IO / notification.htmlする

ここでそれを行うためのスニペットコード:

public FileWatcher(Path dir) {
   this.watcher = FileSystems.getDefault().newWatchService();
   WatchKey key = dir.register(watcher, ENTRY_MODIFY);
}

void processEvents() {
    for (;;) {
        // wait for key to be signalled
        WatchKey key;
        try {
            key = watcher.take();
        } catch (InterruptedException x) {
            return;
        }

        for (WatchEvent<?> event : key.pollEvents()) {
            WatchEvent.Kind<?> kind = event.kind();

            if (kind == OVERFLOW) {
                continue;
            }
            // Context for directory entry event is the file name of entry
            WatchEvent<Path> ev = cast(event);
            Path name = ev.context();
            Path child = dir.resolve(name);
            // print out event
            System.out.format("%s: %s file \n", event.kind().name(), child);
        }
        // reset key and remove from set if directory no longer accessible
        boolean valid = key.reset();
    }
}

使用するJava 7の WatchService に、NIO.2の一部

  

WatchServiceのAPIは、ファイル変更イベントについて通知する必要があるアプリケーション向けに設計されています。

これは、標準ライブラリクラスでは不可能です。詳細については、この質問を参照してください。

は、効率的なポーリングのためには、ランダムアクセスを使用する方がよいでしょうに。それはあなたがファイルの最後端の位置を覚えていて、そこから読み始める場合に役立ちます。

ただ、ニック・フォーテスキューの最後のエントリに展開して、以下の指定したファイルが同時に一つのプロセスによって書き込まれ、別で読み取ることができることを示している(例えば二つの異なるシェル・ウィンドウで)同時に実行できる2つのクラスがあります。

ここでは、2つのプロセスがこれらのJavaクラスを実行されますが、私は、書き込み処理は、他のアプリケーションから可能と思われるものでした。 (それはファイルされている特定のオペレーティング・システム上のが、このようなファイル・システム・ロックの排他ロックを保持していないと仮定すると?)

私は正常にWindozeとLinuxの両方でこれらの2つのクラスをテストしています。私は非常に多く、彼らが失敗した上で、いくつかの条件(例えば、オペレーティングシステム)があるかどうかを知りたいと思います。

クラス#1:

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;

public class FileAppender {

    public static void main(String[] args) throws Exception {
        if ((args != null) && (args.length != 0)) throw
            new IllegalArgumentException("args is not null and is not empty");

        File file = new File("./file.txt");
        int numLines = 1000;
        writeLines(file, numLines);
    }

    private static void writeLines(File file, int numLines) throws Exception {
        PrintWriter pw = null;
        try {
            pw = new PrintWriter( new FileWriter(file), true );
            for (int i = 0; i < numLines; i++) {
                System.out.println("writing line number " + i);
                pw.println("line number " + i);
                Thread.sleep(100);
            }
        }
        finally {
            if (pw != null) pw.close();
        }
    }

}

クラス#2:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class FileMonitor {

    public static void main(String[] args) throws Exception {
        if ((args != null) && (args.length != 0)) throw
            new IllegalArgumentException("args is not null and is not empty");

        File file = new File("./file.txt");
        readLines(file);
    }

    private static void readLines(File file) throws Exception {
        BufferedReader br = null;
        try {
            br = new BufferedReader( new FileReader(file) );
            while (true) {
                String line = br.readLine();
                if (line == null) { // end of file, start polling
                    System.out.println("no file data available; sleeping..");
                    Thread.sleep(2 * 1000);
                }
                else {
                    System.out.println(line);
                }
            }
        }
        finally {
            if (br != null) br.close();
        }
    }

}

残念ながら、ファイルの末尾を監視するために使用することができTailInputStreamクラスは、標準のJavaプラットフォームクラスの一つではなく、ウェブ上のいくつかの実装があります。あなたは http://www.greentelligent.com/java上の使用例と一緒にTailInputStreamクラスの実装を見つけることができます/ tailinputstreamするます。

ポーリング、一貫性サイクルに又はランダムサイクルのいずれか。 200-2000msは良いランダムポーリング間隔スパンでなければなりません。

二つのことを確認してください...

あなたは、ファイルの成長を監視する必要がある場合は、

、その後、EOF /バイト数をチェックして、小娘の世論調査でいるとFileAccessのかFILEWRITE時間を比較するようにしてください。場合(>)、そのファイルが書き込まれています。

すると、排他ロックのチェックで/アクセスを読むことを兼ね備えています。ファイルが読み取りロックすることができ、それが成長してきた場合、それが終了したと書いていたものは何でも。

単独のプロパティのいずれかの確認は必ずしも++あなたのを書かれたの保証状態を取得することはありませんとの実際に行われ、使用可能。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top