From 6ddaaf8555d6b94684d061289249cac67c6eb09f Mon Sep 17 00:00:00 2001 From: Szymon Szukalski Date: Wed, 3 Oct 2012 10:45:23 +1000 Subject: Added example of SimpleFileVisitor usage --- .../java/io/skas/melbjvm/nio2/VisitingWatcher.java | 111 +++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/main/java/io/skas/melbjvm/nio2/VisitingWatcher.java (limited to 'src/main/java/io/skas/melbjvm/nio2/VisitingWatcher.java') diff --git a/src/main/java/io/skas/melbjvm/nio2/VisitingWatcher.java b/src/main/java/io/skas/melbjvm/nio2/VisitingWatcher.java new file mode 100644 index 0000000..4ea5ef1 --- /dev/null +++ b/src/main/java/io/skas/melbjvm/nio2/VisitingWatcher.java @@ -0,0 +1,111 @@ +package io.skas.melbjvm.nio2; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashMap; +import java.util.Map; + +/** + * VisitingWatcher is a watch service that watches a directory tree using the + * SimpleFileVisitor to register directory trees created within the watched + * directory. + * + * @author Szymon Szukalski [szymon.szukalski@gmail.com] + */ +public class VisitingWatcher { + + private static final Logger LOG = LoggerFactory.getLogger(VisitingWatcher.class); + + private WatchService watchService; + private final Map watchedPaths = new HashMap(); + + private void registerDirectory(Path directory) throws IOException { + + WatchKey key = directory.register( + watchService, + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_MODIFY, + StandardWatchEventKinds.ENTRY_DELETE); + + watchedPaths.put(key, directory); + + } + + private void registerTree(Path startingDirectory) throws IOException { + + Files.walkFileTree(startingDirectory, new SimpleFileVisitor() { + /** + * Invoked for a directory before entries in the directory are visited. + *

+ *

Unless overridden, this method returns {@link java.nio.file.FileVisitResult#CONTINUE + * CONTINUE}. + */ + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + LOG.debug("registering: {}", dir); + registerDirectory(dir); + return FileVisitResult.CONTINUE; + } + }); + + } + + public void watchDirectory(Path directory) throws IOException, InterruptedException { + + watchService = FileSystems.getDefault().newWatchService(); + registerTree(directory); + + while (true) { + + // retrieve and remove the next watch key (waits) + final WatchKey key = watchService.take(); + + // get list of events for the key + for (WatchEvent watchEvent : key.pollEvents()) { + + // get the event kind + final WatchEvent.Kind kind = watchEvent.kind(); + + // get the filename for the event + final WatchEvent watchEventPath = (WatchEvent) watchEvent; + final Path filename = watchEventPath.context(); + + LOG.debug("event: {} filename: {}", kind, filename); + + // handle OVERFLOW event + if (kind == StandardWatchEventKinds.OVERFLOW) { + continue; + } + + // handle CREATE event + if (kind == StandardWatchEventKinds.ENTRY_CREATE) { + final Path directoryPath = watchedPaths.get(key); + final Path child = directoryPath.resolve(filename); + + if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) { + registerTree(child); + } + } + } + + // reset the key + boolean valid = key.reset(); + + // remove the key from watched paths if the key is not valid + // (if the directory was deleted, for example) + if (!valid) { + watchedPaths.remove(key); + + if (watchedPaths.isEmpty()) { + break; + } + } + } + + watchService.close(); + } +} \ No newline at end of file -- cgit v1.2.3