24
import java.io.*;
import java.nio.file.*;

public class Tmp {

    public static void main(String [] args) throws IOException {
        int count = 0;
        Path path = Paths.get("C:\\tmp\\");
        WatchService ws = null;
        try {
            ws = FileSystems.getDefault().newWatchService();
            path.register(ws, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE,
                    StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.OVERFLOW);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        while(true) {
            WatchKey key = null;
            try {
                key = ws.take();
            } catch(InterruptedException ie) {
                ie.printStackTrace();
            }

            for(WatchEvent<?> event: key.pollEvents()) {
                switch(event.kind().name()) {
                    case "OVERFLOW":
                        System.out.println(++count + ": OVERFLOW");
                        break;
                    case "ENTRY_MODIFY":
                        System.out.println(++count + ": File " + event.context() + " is changed!");
                        break;
                    case "ENTRY_CREATE":
                        System.out.println(++count + ": File " + event.context() + " is created!");
                        break;
                    case "ENTRY_DELETE":
                        System.out.println(++count + ": File " + event.context() + " is deleted!");
                        break;
                    default:
                        System.out.println(++count + ": UNKNOWN EVENT!");
                }
            }

            key.reset();
        }    
    }
}

これを実行して Notepad ++ を開き、新しい空のファイルを作成a.txtしてC:\tmp\ディレクトリに保存すると、出力が得られました。

1: File a.txt is created!
2: File a.txt is deleted!
3: File a.txt is created!

何故ですか?ファイルが作成されてから削除され、再度作成されたようです。なんで?

ファイルにテキストを入力して保存すると、出力は次のようになりました。

4: File a.txt is changed!
5: File a.txt is changed!

なぜ2回変わったのですか?

4

4 に答える 4

2

Watch Service の Modify イベントは、2 つのイベントを生成します。既存のファイルを変更する場合、ファイル システムは最初にファイルを 0 バイトで作成し、変更イベントを発生させてからデータを書き込みます。次に、変更イベントを再度発生させます。そのため、2 つの変更イベントが表示されていました。したがって、この問題を解決するために行ったことは、カウンターを使用して、タスクが偶数カウントで1回だけトリガーされることを確認するだけです

        Path path = null;
        int count = 0;

        try {
            path = Paths.get(new Utility().getConfDirPath());
            System.out.println("Path: " + path);
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }

        WatchService watchService = null;
        try {
            watchService = FileSystems.getDefault().newWatchService();
            path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }


        while(true) {
            WatchKey key = null;
            try {
                key = watchService.take();
            } catch(InterruptedException ie) {
                ie.printStackTrace();
            }

            for(WatchEvent<?> event: key.pollEvents()) {
                switch(event.kind().name()) {
                    case "ENTRY_MODIFY":
                        System.out.println(++count + ": File " + event.context() + " is changed!");

                        if (count%2==0) {
                            doOnChange(); // do whatever you want
                        }
                        break;
                    case "ENTRY_DELETE":
                        System.out.println(++count + ": File " + event.context() + " is deleted!");
                        break;
                    default:
                        System.out.println(++count + ": UNKNOWN EVENT!");
                }
            }

            // reset the key
            boolean valid = key.reset();
            if (!valid) {
                System.out.println("Key has been unregistered");
            }

        }    
于 2016-12-22T07:24:03.140 に答える
0

ファイルの作成と削除のイベントは、私のシステム (Windows 7 + 1.7.0_21) で正しく機能しています。

変更イベント メッセージは、そのファイルに対する操作ごとに回数 (n) 回表示されCtrlますs

      // Removed the "//" after director name as D://tmp"
      //Added just to see the message with a 1 ms gap.
      Thread.sleep(1000); // after key.reset();

例:ファイルを開いてcrtl + sを押し続けると(変更なしで保存/変更ありで保存)。次のメッセージは、保存操作ごとに (繰り返し) 表示されます。

     File YourFileName.txt is changed!

理由は、Windows では、WatchService がファイルの変更をチェックサムではなくタイムスタンプと比較しているためです。

詳細はこちらプラットフォームの依存関係

于 2013-05-19T14:06:41.963 に答える