Today, We walk you through a Java 8 Watchservice Example in easy steps. You will know how to watch a directory along with subdirectories and files inside there. Beside, we implement a full java program that demonstrates all watched events like ENTRY_CREATE
, ENTRY_DELETE
, ENTRY_MODIFY.
Now, let’s dig into it.
Java 8 Watchservice Example
Register a single directory to Java watcher
We create a method that accepts the path of a directory where we want to watch and which events want to watch like ENTRY_CREATE
, ENTRY_DELETE
, ENTRY_MODIFY
.
1 2 3 4 5 |
private void registerDir(Path dir) throws IOException { WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); keyMap.put(key, dir); } |
Watch directory, sub-directories, and files
We will traversal recursively all directory and subdirectories from a parent directory and call the registerDir
method for each directory we encounter.
1 2 3 4 5 6 7 8 9 10 |
private void traversalDirectories(final Path parentPath) throws IOException { // register directory and sub-directories and files Files.walkFileTree(parentPath, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { registerDir(dir); return FileVisitResult.CONTINUE; } }); } |
Watching for change events
We use pollEvents()
method to get changes occurred on directory and file inside it.
1 2 3 4 5 6 7 8 |
WatchKey watchKey = null; while (true) { watchKey = watchService.poll(10, TimeUnit.MINUTES); if(watchKey != null) { watchKey.pollEvents().stream().forEach(event -> System.out.println(event.context())); } watchKey.reset(); // reset all keys in ready state again } |
If you are using the same key to get events multiple times in a loop, you must call watchKey.reset()
method that reset key in ready state again.
Watching a created directory event
Anytime, a new directory is created, it should be registered with watchservice
, look into code snippet below.
1 2 3 4 5 6 7 8 9 10 |
WatchEvent.Kind kind = event.kind(); if (kind == ENTRY_CREATE) { try { if (Files.isDirectory(child)) { traversalDirectories(child); } } catch (IOException x) { // do stuff } } |
Creating a program for Java 8 Watchservice Example
Now, we create a full program that demonstrates all the cases above. This program will watch a directory, on my local e.g: D:/backup
. Here is detail implementation of Java 8 Watchservice Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
package com.javabycode; import static java.nio.file.StandardWatchEventKinds.*; 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.Paths; 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; public class Java8WatchServiceExample { private final WatchService watchService; private final Map<WatchKey, Path> keyMap; /** * Constructor that creates a WatchService for watching a directory */ Java8WatchServiceExample(Path dir) throws IOException { this.watchService = FileSystems.getDefault().newWatchService(); this.keyMap = new HashMap(); traversalDirectories(dir); } /** * Register a directory with the WatchService */ private void registerDir(Path dir) throws IOException { WatchKey key = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); keyMap.put(key, dir); } /** * Traversal recursively all directory and subdirectories */ private void traversalDirectories(final Path start) throws IOException { Files.walkFileTree(start, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { registerDir(dir); return FileVisitResult.CONTINUE; } }); } /** * Process all events */ void processEvents() { for (;;) { // try/catch that waits for key to be triggered WatchKey key; try { key = watchService.take(); } catch (InterruptedException x) { return; } Path dir = keyMap.get(key); if (dir == null) { System.out.println("Key not recognized!!"); continue; } for (WatchEvent<?> event : key.pollEvents()) { WatchEvent.Kind kind = event.kind(); Path name = ((WatchEvent<Path>)event).context(); Path child = dir.resolve(name); // print out watched event System.out.format("%s: %s\n", event.kind().name(), child); // if directory is created if (kind == ENTRY_CREATE) { try { if (Files.isDirectory(child)) { traversalDirectories(child); } } catch (IOException x) { // do stuff } } } // refine(reset/remove) watchkey map if directory is not valid boolean valid = key.reset(); if (!valid) { keyMap.remove(key); // all of watch keyMap are inaccessible if (keyMap.isEmpty()) { break; } } } } public static void main(String[] args) throws IOException { //a directory is watched Path dir = Paths.get("D:/backup"); new Java8WatchServiceExample(dir).processEvents(); } } |
Before running the program, the directory D:/backup
contains some things like below
Now, we run the above program then rename a file in that directory and create a new folder then rename that folder. We will see the output below:
That’s all about Java 8 Watchservice Example. You may be interested in other Java 8 tutorials
If you find this post useful, don't hesitate to share it with your friends or other people for growing knowledge together and is an effort to contribute us.