java
49 lines · 8 steps
Watching a directory with Java NIO
A small AutoCloseable wrapper around WatchService that reports file creates, modifies, and deletes as they happen.
Explained by
highlit
1package com.example.fs;
2
3import java.io.IOException;
4import java.nio.file.FileSystems;
5import java.nio.file.Path;
6import java.nio.file.StandardWatchEventKinds;
7import java.nio.file.WatchEvent;
8import java.nio.file.WatchKey;
9import java.nio.file.WatchService;
10
11public class DirectoryWatcher implements AutoCloseable {
12
13 private final Path directory;
14 private final WatchService watchService;
15
16 public DirectoryWatcher(Path directory) throws IOException {
17 this.directory = directory;
18 this.watchService = FileSystems.getDefault().newWatchService();
19 directory.register(
20 watchService,
21 StandardWatchEventKinds.ENTRY_CREATE,
22 StandardWatchEventKinds.ENTRY_MODIFY,
23 StandardWatchEventKinds.ENTRY_DELETE);
24 }
25
26 public void watch() throws InterruptedException {
27 while (true) {
28 WatchKey key = watchService.take();
29 for (WatchEvent<?> event : key.pollEvents()) {
30 WatchEvent.Kind<?> kind = event.kind();
31 if (kind == StandardWatchEventKinds.OVERFLOW) {
32 continue;
33 }
34 @SuppressWarnings("unchecked")
35 WatchEvent<Path> ev = (WatchEvent<Path>) event;
36 Path changed = directory.resolve(ev.context());
37 System.out.printf("%s -> %s%n", kind.name(), changed);
38 }
39 if (!key.reset()) {
40 break;
41 }
42 }
43 }
44
45 @Override
46 public void close() throws IOException {
47 watchService.close();
48 }
49}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1WatchService turns filesystem changes into a blocking event stream you consume in a loop.
- 2Calling reset() after draining a WatchKey is mandatory — skip it and you stop receiving events.
- 3Implementing AutoCloseable lets try-with-resources guarantee the native watch handle is released.
Related explainers
python
import hashlib from collections import defaultdict from pathlib import Path
Finding duplicate files by size then hash
hashing
file-io
deduplication
Intermediate
7 steps
java
@Component public class HeaderMergeFilter { private static final String PER_REQUEST_HEADERS = HeaderMergeFilter.class.getName() + ".headers";
Merging default and per-request headers in Spring
webclient
filters
http-headers
Intermediate
8 steps
rust
use std::fs::File; use std::io::{Read, Seek, SeekFrom}; #[derive(Debug)]
Parsing an HTTP Range header in Rust
http-range
parsing
file-io
Intermediate
10 steps
java
import java.util.HashSet; import java.util.Set; public final class CollectionDiff<T> {
Diffing two collections with set operations
set-operations
immutability
generics
Intermediate
8 steps
java
public record AppConfig( String host, int port, String databaseUrl,
Loading typed config from env vars in Java
records
configuration
environment-variables
Intermediate
6 steps
ruby
require "charlock_holmes" class TextFileNormalizer DEFAULT_CONFIDENCE = 60
Normalizing text files to clean UTF-8 in Ruby
encoding
text-processing
file-io
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/watching-a-directory-with-java-nio-explained-java-0a79/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.