Three Java Ways to Dynamically Monitor File Changes: Polling, WatchService, and Commons‑IO
To handle dynamic file changes such as rule updates, configuration reloads, or log monitoring, this article compares three Java approaches—simple polling with File#lastModified, the OS‑integrated WatchService API, and the Apache Commons‑IO monitor—detailing their implementations, advantages, drawbacks, and practical usage tips.
Background
When rules or configuration files are stored as files, an application often needs to detect changes and reload them. The same requirement appears in scenarios such as dynamic configuration reload, log file monitoring, or FTP file change detection.
Solution 1: Scheduled Task + File#lastModified
The simplest approach is to run a periodic task that reads File.lastModified() and compares it with the previous timestamp. If the value differs, the file has been modified and the application can reload it.
public class FileWatchDemo {
public static long LAST_TIME = 0L;
public static void main(String[] args) throws IOException {
String fileName = "/Users/zzs/temp/1.txt";
createFile(fileName);
for (int i = 0; i < 2; i++) {
long timestamp = readLastModified(fileName);
if (timestamp != LAST_TIME) {
System.out.println("文件已被更新:" + timestamp);
LAST_TIME = timestamp;
// reload file content
} else {
System.out.println("文件未更新");
}
}
}
public static void createFile(String fileName) throws IOException {
File file = new File(fileName);
if (!file.exists()) {
boolean result = file.createNewFile();
System.out.println("创建文件:" + result);
}
}
public static long readLastModified(String fileName) {
File file = new File(fileName);
return file.lastModified();
}
}This method works for low‑frequency file changes but incurs overhead from repeated polling and state comparison. It also suffers from known bugs in File#lastModified on Java 8/9.
Solution 2: WatchService
Java 7 introduced java.nio.file.WatchService, an OS‑level file system monitor that can watch directories for creation, deletion, and modification events without manual polling.
public class WatchServiceDemo {
public static void main(String[] args) throws IOException {
Path path = Paths.get("/Users/zzs/temp/");
WatchService watcher = FileSystems.getDefault().newWatchService();
path.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
try {
while (true) {
WatchKey key = watcher.take();
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
continue;
}
Path fileName = (Path) event.context();
System.out.println("文件更新: " + fileName);
}
if (!key.reset()) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}Supported event kinds include:
ENTRY_CREATE – file created
ENTRY_DELETE – file deleted
ENTRY_MODIFY – file modified
OVERFLOW – events lost
Internally, WatchService runs a dedicated thread (e.g., PollingWatchService) that polls the OS at a configurable interval. The default sensitivity levels are defined in SensitivityWatchEventModifier (HIGH = 2 s, MEDIUM = 10 s, LOW = 30 s) and can be passed when registering the path.
path.register(watcher, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY},
SensitivityWatchEventModifier.HIGH);Advantages: no manual polling, higher efficiency. Drawbacks: only monitors a single directory (no recursive sub‑directory watching), and the notification latency is limited to the chosen sensitivity interval.
Solution 3: Apache Commons‑IO
Commons‑IO provides a ready‑made file‑monitoring framework in the org.apache.commons.io.monitor package.
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>Typical usage steps:
Create a listener by extending FileAlterationListenerAdaptor and override methods for create, modify, delete events.
Instantiate a FileAlterationObserver for the target directory (optionally with a filter).
Attach the observer to a FileAlterationMonitor with a polling interval.
Start the monitor.
public class FileListener extends FileAlterationListenerAdaptor {
@Override
public void onFileCreate(File file) {
System.out.println("新建:" + file.getAbsolutePath());
// TODO: reload file content
}
@Override
public void onFileChange(File file) {
System.out.println("修改:" + file.getAbsolutePath());
}
@Override
public void onFileDelete(File file) {
System.out.println("删除:" + file.getAbsolutePath());
}
// other callbacks omitted for brevity
} public class FileMonitor {
private FileAlterationMonitor monitor;
public FileMonitor(long interval) {
monitor = new FileAlterationMonitor(interval);
}
public void monitor(String path, FileAlterationListener listener) {
FileAlterationObserver observer = new FileAlterationObserver(new File(path));
monitor.addObserver(observer);
observer.addListener(listener);
}
public void start() throws Exception { monitor.start(); }
public void stop() throws Exception { monitor.stop(); }
} public class FileRunner {
public static void main(String[] args) throws Exception {
FileMonitor fileMonitor = new FileMonitor(1000);
fileMonitor.monitor("/Users/zzs/temp/", new FileListener());
fileMonitor.start();
}
}Running the demo prints log messages each second; when a file changes, the corresponding event method is invoked. The polling interval can be adjusted when constructing FileMonitor. Filters can be applied via the observer’s constructor to watch only specific files.
Conclusion
All three Java‑based file‑watching techniques have trade‑offs. Simple polling is easy but inefficient; WatchService offers OS‑level efficiency but limited to a single directory and coarse latency; Commons‑IO provides a flexible, configurable solution with built‑in filtering. Choose the approach that best matches your application’s performance requirements and directory‑structure complexity.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Senior Brother's Insights
A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
