A watchService enables we to set up a process that reacts to changes within a directory. That is, it watches registered objects for changes and events. For example a file manager may use a watch service to monitor a directory for changes so that it can update its display of the list of files when files are created or deleted.
// files/PathWatcher.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {ExcludeFromGradle}
import static java.nio.file.StandardWatchEventKinds.*;
import java.io.IOException;
import java.nio.file.*;
import java.util.concurrent.*;
public class PathWatcher {
static Path test = Paths.get("test");
static void delTxtFiles() {
try {
Files.walk(test)
.filter(f -> f.toString().endsWith(".txt")) // must be f.toString()
.forEach(
f -> {
try {
System.out.println("deleting " + f);
Files.delete(f);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws Exception {
Directories.refreshTestDir();
Directories.populateTestDir();
System.out.println("test:" + test);
Files.createFile(test.resolve("Hello.txt"));
WatchService watcher = FileSystems.getDefault().newWatchService();
test.register(watcher, ENTRY_DELETE);
Executors.newSingleThreadScheduledExecutor()
.schedule(PathWatcher::delTxtFiles, 250, TimeUnit.MILLISECONDS);
WatchKey key = watcher.take();
for (WatchEvent evt : key.pollEvents()) {
System.out.println(
"evt.context(): "
+ evt.context()
+ "\nevt.count(): "
+ evt.count()
+ "\nevt.kind(): "
+ evt.kind());
System.exit(0);
}
}
}
/* My Output:
test:test
deleting test/foo/bar/baz/bag/File.txt
deleting test/baz/bag/foo/bar/File.txt
deleting test/bar/baz/bag/foo/File.txt
deleting test/bag/foo/bar/baz/File.txt
deleting test/Hello.txt
*/
schedule
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay,
TimeUnit unit)
Description copied from interface: ScheduledExecutorService
Creates and executes a ScheduledFuture that becomes enabled after the given delay.
Specified by:
schedule
in interface ScheduledExecutorService
Type Parameters:
V
- the type of the callable's result
Parameters:
callable
- the function to execute
delay
- the time from now to delay execution
unit
- the time unit of the delay parameter
Returns:
a ScheduledFuture that can be used to extract result or cancel
Throws:
RejectedExecutionException
- if the task cannot be scheduled for execution
NullPointerException
- if callable is null
take
WatchKey take()
throws InterruptedException
Retrieves and removes next watch key, waiting if none are yet present.
Returns:
the next watch key
Throws:
ClosedWatchServiceException
- if this watch service is closed, or it is closed while waiting for the next key
InterruptedException
- if interrupted while waiting
// files/TreeWatcher.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {ExcludeFromGradle}
import static java.nio.file.StandardWatchEventKinds.*;
import java.io.IOException;
import java.nio.file.*;
import java.util.concurrent.*;
public class TreeWatcher {
static void watchDir(Path dir) {
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
dir.register(watcher, ENTRY_DELETE);
Executors.newSingleThreadExecutor()
.submit(
() -> {
try {
WatchKey key = watcher.take();
for (WatchEvent evt : key.pollEvents()) {
System.out.println(
"evt.context(): "
+ evt.context()
+ "\nevt.count(): "
+ evt.count()
+ "\nevt.kind(): "
+ evt.kind());
System.exit(0);
}
} catch (InterruptedException e) {
return;
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws Exception {
Directories.refreshTestDir();
Directories.populateTestDir();
Files.walk(Paths.get("test")).filter(Files::isDirectory).forEach(TreeWatcher::watchDir);
PathWatcher.delTxtFiles();
}
}
/* My Output:
deleting test/foo/bar/baz/bag/File.txt
deleting test/baz/bag/foo/bar/File.txt
deleting test/bar/baz/bag/foo/File.txt
deleting test/bag/foo/bar/baz/File.txt
evt.context(): File.txt
evt.count(): 1
evt.kind(): ENTRY_DELETE
*/
references:
1. On Java 8 - Bruce Eckel
2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/files/PathWatcher.java
4. https://docs.oracle.com/javase/8/docs/api/java/nio/file/WatchService.html
5. https://blog.youkuaiyun.com/wangbingfengf98/article/details/89425199
6. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/files/TreeWatcher.java