WatchService in Java
The WatchService API in Java, in java.nio.file, lets a program watch a folder and be told when files in it are created, modified or deleted. It is used for things like reloading a configuration file when it changes, processing files dropped into an "inbox" folder, or refreshing a file list in an editor. You register a folder with a watch service, then wait for watch keys that carry the events. In this lesson, you will learn the steps and build a small inbox watcher.
Steps
- Create a watch service:
FileSystems.getDefault().newWatchService(). - Register a folder for event kinds:
dir.register(watcher, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE). - Wait for a key:
watcher.take()(waits forever) orwatcher.poll(timeout, unit). - Read its events:
key.pollEvents(); each event has akind()and acontext()(the file name). - Call
key.reset()so the key can report more events.
Event Kinds
| Kind | Meaning |
|---|---|
ENTRY_CREATE | A file or folder was created or moved in |
ENTRY_MODIFY | A file's contents or attributes changed |
ENTRY_DELETE | A file or folder was deleted or moved out |
OVERFLOW | Events were lost because too many happened at once |
Example: Watching an Inbox Folder
Let's see an example that watches a folder and reacts when a file appears. On some systems, such as macOS, the JDK checks folders every few seconds, so the event can take a moment to arrive.
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.concurrent.TimeUnit;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
public class InboxWatcher {
public static void main(String[] args)
throws IOException, InterruptedException {
Path inbox = Files.createDirectories(Path.of("inbox"));
try (WatchService watcher =
FileSystems.getDefault().newWatchService()) {
inbox.register(watcher, ENTRY_CREATE);
System.out.println("Watching " + inbox);
Files.writeString(inbox.resolve("navika-homework.txt"), "done");
WatchKey key = watcher.poll(15, TimeUnit.SECONDS);
if (key == null) {
System.out.println("No events in time");
return;
}
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind() == ENTRY_CREATE) {
Path name = (Path) event.context();
System.out.println("New file: " + name + " ("
+ Files.size(inbox.resolve(name)) + " bytes)");
}
}
key.reset();
}
}
}Watching inbox
New file: navika-homework.txt (4 bytes)Explanation: The inbox folder is registered for ENTRY_CREATE events. When a file is written into it, the watch service queues a key. poll waits up to 15 seconds for it. Each event's context() is the file's name relative to the folder, so inbox.resolve(name) gives its full path. A real watcher would loop, calling take() and reset() forever.
Watching Folder Trees
Common Mistakes
Forgetting key.reset(). The key stops reporting events.
Treating the context as a full path. Resolve it against the watched folder.
Expecting events from subfolders. Register them too.
Practice
- Easy: Watch a folder and print every create, modify and delete event until a file named
stopis created. - Harder: Write an inbox processor that moves every new
.csvfile into aprocessedfolder after printing its number of lines.
Key Takeaways
Was this tutorial helpful?