3

Observer パターンが、ログ ファイルとその変更を監視するコードを実装するための正しいアプローチであるかどうかを知りたいですか?

現在使用中ですが、うまく説明できない異常があるようです。基本的に、変更された「lastmodified 日付」を探して一意のファイルのリストを反復する、起動するタイマーを持つ FileMonitor というクラスを作成します。

それが見つかると、一致するファイルを見つけるためにリスナーのリストが繰り返され、その fileChanged イベントが通知されます。次に、ファイルに追加された行の処理を開始します。

だから私の質問をより簡潔にするために:

  1. オブザーバー パターンは、私がやろうとしていることに合いますか? (現在、ファイルごとに 1 つのリスナーがあります)
  2. 監視するファイルが複数ある場合、「同時実行の問題」が発生する可能性はありますか?

ありがとう

4

4 に答える 4

5

Java 7 ではWatchService、登録されたオブジェクトの変更とイベントを監視する機能が導入されました。

Watchable オブジェクトは、その register メソッドを呼び出すことによってウォッチ サービスに登録され、登録を表す WatchKey が返されます。オブジェクトのイベントが検出されると、キーが通知されます。現在通知されていない場合は、監視サービスのキューに入れられ、ポーリングを呼び出すか、メソッドを取得してキーを取得し、イベントを処理するコンシューマーがキーを取得できるようにします。イベントが処理されると、コンシューマーはキーのリセット メソッドを呼び出してキーをリセットします。これにより、キーにシグナルを送信し、さらなるイベントで再度キューに入れることができます。

ファイル システムは、イベントを取得または処理するよりも速くレポートする場合があり、実装によって、蓄積できるイベントの数に不特定の制限が課される場合があります。実装が意図的にイベントを破棄する場合、キーの pollEvents メソッドが OVERFLOW のイベント タイプを持つ要素を返すように調整します。このイベントは、コンシューマーがオブジェクトの状態を再検査するためのトリガーとして使用できます。

例 -

Path myDir = Paths.get("D:/test");       

    try {
       WatchService watcher = myDir.getFileSystem().newWatchService();
       myDir.register(watcher, StandardWatchEventKind.ENTRY_CREATE, 
       StandardWatchEventKind.ENTRY_DELETE, StandardWatchEventKind.ENTRY_MODIFY);

       WatchKey watckKey = watcher.take();

       List<WatchEvent<?>> events = watckKey.pollEvents();
       for (WatchEvent event : events) {
            if (event.kind() == StandardWatchEventKind.ENTRY_CREATE) {
                System.out.println("Created: " + event.context().toString());
            }
            if (event.kind() == StandardWatchEventKind.ENTRY_DELETE) {
                System.out.println("Delete: " + event.context().toString());
            }
            if (event.kind() == StandardWatchEventKind.ENTRY_MODIFY) {
                System.out.println("Modify: " + event.context().toString());
            }
        }

    } catch (Exception e) {
        System.out.println("Error: " + e.toString());
    }
}

参照 -リンク

于 2013-02-07T08:58:19.293 に答える
4

Java 7 を使用したくない場合は、Apache IOで同じ動作を得ることができます。

公式ドキュメントから:

FileAlterationObserver は、ルート ディレクトリ以下のファイルの状態を表し、ファイル システムをチェックし、作成、変更、または削除イベントをリスナーに通知します。

リスナーを追加して、そのようなイベントが発生したときに実行される操作を定義する方法を次に示します。

  File directory = new File(new File("."), "src");
  FileAlterationObserver observer = new FileAlterationObserver(directory);
  observer.addListener(...);
  observer.addListener(...);

オブザーバを で登録する必要がありFileAlterationMonitorます。同じドキュメントから続ける:

  long interval = ...
  FileAlterationMonitor monitor = new FileAlterationMonitor(interval);
  monitor.addObserver(observer);
  monitor.start();
  ...
  monitor.stop();

は、ファイル システムのチェック間で待機intervalする時間 (ミリ秒単位) です。

org.apache.commons.io.monitorライブラリで指定されたパッケージを探します。

于 2013-02-07T09:09:04.777 に答える
3

オブザーバー パターンは、私がやろうとしていることに合いますか? (現在、ファイルごとに 1 つのリスナーがあります)

はい、そうです。

監視するファイルが複数ある場合、「同時実行の問題」が発生する可能性はありますか?

によってバックアップされたリストに対してリスナーを削除および追加する複数のスレッドがArrayListある場合、ConcurrentModificationException. CopyOnWriteArrayList代わりにaを使用してください。

IIRC の効果的な Java には、同じことに関する良い例を含む記事があります。

于 2013-02-07T09:00:53.653 に答える
0

NIOに行くことをお勧めします

および File Watcher サービス -ファイルの変更の監視

于 2013-02-07T08:57:46.507 に答える