2

I have the following files and folders structure:

/root/

/root/pictures/

/root/pictures/picture1.jpg

/root/pictures/picture2.jpg

I registered two WatchServices, one for the /root/ folder and one for /root/pictures. For both I registered the events: ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY.

When I delete /root/pictures/ I expect to get one ENTRY_DELETE event for the deletion of the folder /root/pictures/ and two ENTRY_DELETE events for picture1.jpg and picture2.jpg. In fact I only get the ENTRY_DELETE event for /root/pictures/. When I only delete picture1.jpg I get one delete event as expected.

Is that normal behaviour? How can I get the list of files that were inside a deleted folder with WatchService?

bamboofighter
  • 299
  • 1
  • 14

3 Answers3

1

You did not show any code, so we don't know how you tried to implement it, but the following seems to work to get ENTRY_DELETE events for files within a directory if the directory itself is deleted (please note that it contains only one WatchService, for directory xxx/yyy; I have not included the other WatchService for directory xxx)

public class WatchServiceApp {

    public static void main(String[] args) throws IOException {
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Path dirPath = Paths.get("/home/myuser/xxx/yyy");
        WatchKey watchKey = dirPath.register(
                watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

        while (true) {
            try {
                watchService.take();
            } catch (InterruptedException ex) {
                break;
            }

            List<WatchEvent<?>> watchEventList = watchKey.pollEvents();
            for (WatchEvent<?> watchEvent : watchEventList) {
                Path filePath = (Path) watchEvent.context();
                System.out.println("Event " + watchEvent.kind() + " for " + filePath.toString());
            }

            boolean watchKeyValid = watchKey.reset();
            if (!watchKeyValid) {
                break;
            }
        }
    }

}

Lets assume the directory xxx/yyy contains three files. First we delete individual file3 and get

Event ENTRY_DELETE for file3

then we delete the entire yyy directory and get

Event ENTRY_DELETE for file2
Event ENTRY_DELETE for file1
hammerfest
  • 2,203
  • 1
  • 20
  • 43
  • Thanks for your code. That's really interesting because it works not as expected for me. When I delete the watched folder the program stops and will not give any output. When I just delete a single file inside the watched folder I'll get the output. – bamboofighter Oct 13 '16 at 18:40
  • I should add that I'm running the code unter Mac OS 10.12. Might it be a bug that only occurs on Mac OS? – bamboofighter Oct 13 '16 at 18:42
  • You receive the events for the entries within the directory but not for the directory itself. In your code you also receive an event for the directory itself because you have another WatchService created for its parent directory. That's why I emphasized that WatchService is not present in my code. OS most likely should not make any difference in this regard. – hammerfest Oct 13 '16 at 21:20
  • Yes, in my original code I got multiple WatchServices running. But I tried your code exactly as you described it and didn't get the notification for the files when I created a WatchService for /xxx/yyy and moved /xxx/yyy to bin. – bamboofighter Oct 14 '16 at 07:11
  • This means that you did have some files existing within /xxx/yyy (i.e. it was not empty) when you deleted it, and you did not get any delete events for those files unlike I did for file1 and file2 in my example? – hammerfest Oct 14 '16 at 07:28
  • Yes correct. I don't get the same results as you in your example. Shortly after I delete the not empty /xxx/yyy folder your example app quits and does not print any message. – bamboofighter Oct 14 '16 at 07:38
  • The app is intentionally quitting after you have deleted the registered directory; that's where the code breaks the endless while loop; you can check this by adding some log printouts to the code. Why the delete events are missing for the files of a non-empty dir being deleted is a good question. Can you try to perform the remove operations from a MAC terminal command line (e.g. rm -r xxx/yyy) instead of Finder or whatever file manager you are currently using? – hammerfest Oct 14 '16 at 07:50
  • 1
    Before I always used Finder to delete the folder and files. I made another attempt to delete the folder from my terminal (rm -r xxx/yyy) and I got the same results. That means the application quits without notifying me about the files that were inside the deleted and watched folder. – bamboofighter Oct 20 '16 at 12:32
  • 1
    Well, it might then indeed be a problem with MAC environment. I do not have that available to try, but some research brought up the following SO thread: http://stackoverflow.com/questions/9588737/is-java-7-watchservice-slow-for-anyone-else which seems to indicate that it is a long time known issue for OSX and that it will still not be fixed in JDK9. You might want to try the solutions suggested in the answers for this thread; use the SensitivityWatchEventModifier class or the native implementation library of WatchService for Mac. Let me know whether any of these solved it for you. – hammerfest Oct 21 '16 at 11:05
0

It looks like you does not deleted your directory finally. I mean, if you delete directory in Windows by key "delete", you will got an event for the deletion of the folder /root/pictures/. But your files will still alive in the trash can. If you will clear trash can - you will get ENTRY_DELETE events for picture1.jpg and picture2.jpg

Snatch
  • 1
0

From the documentation on WatchService (emphasis mine):

Platform dependencies

The implementation that observes events from the file system is intended to map directly on to the native file event notification facility where available, or to use a primitive mechanism, such as polling, when a native facility is not available. Consequently, many of the details on how events are detected, their timeliness, and whether their ordering is preserved are highly implementation specific. [...]

Meaning that much of the way events are delivered is platform dependent. To your question, is that normal behaviour? The answer is: depends on the platform.

TT.
  • 15,774
  • 6
  • 47
  • 88