Why does WatchService generate so many operations?

◇◆丶佛笑我妖孽 提交于 2019-12-03 01:22:23
Rohit Luthra

Watch Service's Modify event generates two events. When we modify an already existing file, the file system first creates it with 0 bytes and fires a modify event and then writes data on it. Then it fires the modify event again. That's why It was showing two modify events. So What I have done to solve this problem, I just use counter to check my task should be triggered only once on even count

        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");
            }

        }    

this works for me

    // get the first event before looping
    WatchKey key = this.watcher.take();

    // reset key (executed twice but not invoke the polled events)
    while (key != null && key.reset() ) { 
      // polled events
      for (final WatchEvent<?> event : key.pollEvents()) {
        System.out.printf("\nGlobal received: %s, event for file: %s\n", event.kind(),
            event.context());

        switch (event.kind().name()) {
        case "ENTRY_CREATE":
          LOGGER.debug("event ENTRY_CREATE");
          break;
        case "ENTRY_DELETE":
          LOGGER.debug("event ENTRY_DELETE");
          break;
        case "ENTRY_MODIFY":
          LOGGER.debug("event ENTRY_MODIFY");
          break;
        default:
          LOGGER.debug("event other [OVERFLOW]");
          break;
        }
      }

      key = this.watcher.take();
    }

I created a small FileWatcher Utility Library: https://github.com/finsterwalder/fileutils

It allows to set a grace period. Multiple events inside the grace period are accumulated and only triggered once.

You should not use Notepad++ for your experiments, since you don't know what Notepad++ is doing. It may be, that Notepad++ is actually writing to a file several times. Or it could write a file with a different name and rename it, when done or whatnot. Write your own code to manipulate files and watch that.

VKPRO

The File creation and deletion events are working correctly in my system(Window 7 + 1.7.0_21).

The change event message is displayed number of time's(n) for each Ctrl+s operation on that file.

      // 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();

Example : If we open the file and keep on pressing the crtl + s (save with out any changes/with changes). The following message will display(repeatedly) for each save operation.

     File YourFileName.txt is changed!

Reason is in windows the WatchService is comparing the file changes with timestamp instead of checksum.

More description given here Platform dependencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!