Search code examples
javawatchservice

WatchService exclude Folders


I am trying to watch a folder for changes. This folder contains subfolders which I do not want to watch. Unfortunately the WatchService notifies me of changes in these subfolders. I guess this happens because the last change date of these folders updates.

So I tried to exlude them:

WatchService service = FileSystems.getDefault().newWatchService();
workPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
            StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
try {
    WatchKey watchKey = watchService.take();
    for (WatchEvent<?> event : watchKey.pollEvents()) {
        @SuppressWarnings("unchecked")
        WatchEvent<Path> ev = (WatchEvent<Path>) event;
        Path fileName = ev.context();
        if (!Files.isDirectory(fileName)) {
            logger.log(LogLevel.DEBUG, this.getClass().getSimpleName(),
                    "Change registered in " + fileName + " directory. Checking configurations.");
            /* do stuff */
        }
    }
    if (!watchKey.reset()) {
        break;
    }
} catch (InterruptedException e) {
    return;
}

This doesn't work though. The resulting path of the context is relative and Files.isDirectory() cannot determine whether it's a directory or a file.

Is there a way to exclude the subfolders?


Solution

  • You can try the below code snippet. In order to get the full path, you need to call resolve() function

    Map<WatchKey, Path> keys = new HashMap<>();
    
        try {
            Path path = Paths.get("<directory u want to watch>");
            FileSystem fileSystem = path.getFileSystem();
            WatchService service = fileSystem.newWatchService();
    
            Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
                    @Override
                    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                        if (<directory you want to exclude>) {
                                return FileVisitResult.SKIP_SUBTREE;
                        }
    
                        WatchKey key = dir.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
                        keys.put(key, dir);
                        return FileVisitResult.CONTINUE;
                    }
            });
    
            WatchKey key = null;
            while (true) {
                key = service.take();
                while (key != null) {
                    WatchEvent.Kind<?> kind;
                    for (WatchEvent<?> watchEvent : key.pollEvents()) {
                        kind = watchEvent.kind();
                        if (OVERFLOW == kind) {
                            continue;
                        }
    
                        Path filePath = ((WatchEvent<Path>) watchEvent).context();
                        Path absolutePath = keys.get(key).resolve(filePath);
    
                        if (kind == ENTRY_CREATE) {
                            if (Files.isDirectory(absolutePath, LinkOption.NOFOLLOW_LINKS)) {
                                WatchKey newDirKey = absolutePath.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
                                keys.put(newDirKey, absolutePath);
                            }
                        }
    
                    }
                    if (!key.reset()) {
                        break; // loop
                    }
                }
            }
        } catch (Exception ex) {
        }