StandardWatchEvents.ENTRY_MODIFY triggers with modifying a subfolder?

1000 views Asked by At

Example: I have my desktop with a subfolder "Desktop/sub"

if only Desktop is registered and once started the WatchService I modify the content of a subfolder.. should it trigger an ENTRY_MODIFY or not? I tried and it does not. It works only for modifying a file within the registered folder (Desktop in this case).

Just asking this question because in a mock exam for OCPJP7 it says that actually even modifying a subfolder such as "Desktop/sub" for example removing a file within "Desktop/sub" it should trigger the event.

However again, I have tried it out and it does not work.

Here is the code:

WatchKey key = ws.poll(5, TimeUnit.SECONDS);

if (key ==null)
{
    continue;
}
List<WatchEvent<?>> lista = key.pollEvents();

for (WatchEvent<?> event : lista)
{
    switch(event.kind().toString())
    {
    case "ENTRY_CREATE": System.out.println("There has been a creation over here: "+event.context());break;
    case "ENTRY_MODIFY": System.out.println("There has been a modification over here: "+event.context());break;
    case "ENTRY_DELETE": System.out.println("There has been a deletion over here: "+event.context());

    }

    key.reset();
}

Thanks in advance.

1

There are 1 answers

9
Sotirios Delimanolis On

The WatchService only looks at the file and folder modifications in the registered Paths.

If you registered

WatchService service = FileSystems.getDefault().newWatchService();
Path path = Paths.get("/Desktop");
path.register(service, StandardWatchEventKinds.ENTRY_MODIFY);

Then adding a folder to Desktop will be seen. Changing a file in Desktop will be seen. Adding a folder to Desktop/Subs will also be seen, because the folder Subs inside Desktop was modified. However, modifying a file in Desktop/Subs will not be seen because that path is not registered with the service.

You can always register all the paths under Desktop recursively

private void registerRecursive(final Path root) throws IOException {
    // register all subfolders
    Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
                return FileVisitResult.CONTINUE;
        }
    });
}

I have not tried on Linux but the following works on Windows

public static void main(String[] args) throws Exception {   

    WatchService service = FileSystems.getDefault().newWatchService();
    Path path = Paths.get("/Desktop");
    path.register(service, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_CREATE);
    WatchKey key = null;
    while(true) {
        key = service.take();

        List<WatchEvent<?>> lista = key.pollEvents();

        for (WatchEvent<?> event : lista)
        {
            switch(event.kind().toString())
            {
            case "ENTRY_CREATE": System.out.println("There has been a creation over here: "+event.context());break;
            case "ENTRY_MODIFY": System.out.println("There has been a modification over here: "+event.context());break;
            case "ENTRY_DELETE": System.out.println("There has been a deletion over here: "+event.context());

            }

            key.reset();
        }
    }
}