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?
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) {
}