Created
June 5, 2016 18:25
-
-
Save fabriziofortino/83eb36c7b48e9b900c1da1d8508245cd to your computer and use it in GitHub Desktop.
Java 8 Recursive WatchService
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.keepithttps; | |
import com.sun.nio.file.SensitivityWatchEventModifier; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.stereotype.Service; | |
import java.io.File; | |
import java.io.IOException; | |
import java.nio.file.FileSystems; | |
import java.nio.file.FileVisitResult; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.SimpleFileVisitor; | |
import java.nio.file.WatchEvent; | |
import java.nio.file.WatchKey; | |
import java.nio.file.WatchService; | |
import java.nio.file.attribute.BasicFileAttributes; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.Executors; | |
import java.util.function.Consumer; | |
import javax.annotation.PostConstruct; | |
import javax.annotation.PreDestroy; | |
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; | |
import static java.nio.file.StandardWatchEventKinds.OVERFLOW; | |
@Service | |
public class RecursiWatcherService { | |
private static final Logger LOG = LoggerFactory.getLogger(RecursiWatcherService.class); | |
@Value("${root.folder}") | |
private File rootFolder; | |
private WatchService watcher; | |
private ExecutorService executor; | |
@PostConstruct | |
public void init() throws IOException { | |
watcher = FileSystems.getDefault().newWatchService(); | |
executor = Executors.newSingleThreadExecutor(); | |
startRecursiveWatcher(); | |
} | |
@PreDestroy | |
public void cleanup() { | |
try { | |
watcher.close(); | |
} catch (IOException e) { | |
LOG.error("Error closing watcher service", e); | |
} | |
executor.shutdown(); | |
} | |
private void startRecursiveWatcher() throws IOException { | |
LOG.info("Starting Recursive Watcher"); | |
final Map<WatchKey, Path> keys = new HashMap<>(); | |
Consumer<Path> register = p -> { | |
if (!p.toFile().exists() || !p.toFile().isDirectory()) { | |
throw new RuntimeException("folder " + p + " does not exist or is not a directory"); | |
} | |
try { | |
Files.walkFileTree(p, new SimpleFileVisitor<Path>() { | |
@Override | |
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { | |
LOG.info("registering " + dir + " in watcher service"); | |
WatchKey watchKey = dir.register(watcher, new WatchEvent.Kind[]{ENTRY_CREATE}, SensitivityWatchEventModifier.HIGH); | |
keys.put(watchKey, dir); | |
return FileVisitResult.CONTINUE; | |
} | |
}); | |
} catch (IOException e) { | |
throw new RuntimeException("Error registering path " + p); | |
} | |
}; | |
register.accept(rootFolder.toPath()); | |
executor.submit(() -> { | |
while (true) { | |
final WatchKey key; | |
try { | |
key = watcher.take(); // wait for a key to be available | |
} catch (InterruptedException ex) { | |
return; | |
} | |
final Path dir = keys.get(key); | |
if (dir == null) { | |
System.err.println("WatchKey " + key + " not recognized!"); | |
continue; | |
} | |
key.pollEvents().stream() | |
.filter(e -> (e.kind() != OVERFLOW)) | |
.map(e -> ((WatchEvent<Path>) e).context()) | |
.forEach(p -> { | |
final Path absPath = dir.resolve(p); | |
if (absPath.toFile().isDirectory()) { | |
register.accept(absPath); | |
} else { | |
final File f = absPath.toFile(); | |
LOG.info("Detected new file " + f.getAbsolutePath()); | |
} | |
}); | |
boolean valid = key.reset(); // IMPORTANT: The key must be reset after processed | |
if (!valid) { | |
break; | |
} | |
} | |
}); | |
} | |
} |
Trap: By attaching a watch service to every subdirectory, now nobody can move those directories.
thank you,if i create directory recursively, return as follows:java.nio.file.FileSystemException:
f:\watchDir\New folder\New folder: The process cannot access the file because it is being used by another process.
it works at http://docs.oracle.com/javase/tutorial/essential/io/examples/WatchDir.java
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please provithe the code with main method..