java nio watchservice 可监听目录中文件创建、修改和删除事件,但仅监控目录层级变化而非文件内容;需用path注册目录并指定entry_create事件,处理后必须调用key.reset(),且不同系统存在兼容性差异。

Java NIO 的 WatchService 可用于监听目录中文件的创建、修改和删除事件,但要注意:它监听的是**目录层级变化**,不是单个文件内容;要监听“文件新增”,需注册目录的 ENTRY_CREATE 事件。
1. 创建 WatchService 并注册目标目录
必须使用 Path 表示目录(不能是文件),并调用 register() 注册 StandardWatchEventKinds.ENTRY_CREATE:
- 注册前确保目录存在且可读,否则抛
IOException - 一个
WatchService可注册多个目录,每个目录独立触发事件 - 推荐使用 try-with-resources 或显式 close,避免资源泄漏
2. 启动监听循环,获取并处理事件
watcher.take() 是阻塞调用,返回包含事件的 WatchKey;需手动 reset 才能继续接收后续事件:
- 每次处理完事件后必须调用
key.reset(),否则该 key 不再有效 - 事件类型为
WatchEvent.Kind>,需用event.kind() == ENTRY_CREATE判断是否为新增 - 事件上下文(
event.context())是相对路径,需结合注册时的目录拼出完整路径
3. 注意事项与常见陷阱
WatchService 在不同系统表现有差异,实际使用需谨慎:
- Linux(inotify)和 macOS(kqueue)支持较好;Windows(ReadDirectoryChangesW)可能延迟或丢失事件
- 不会递归监听子目录,如需监听整个树,需遍历所有子目录并分别注册
- 临时文件(如编辑器生成的 .swp、~ 结尾文件)也可能触发 ENTRY_CREATE,建议按文件名过滤
- 高并发写入时可能合并多个事件到一个 key 中,需遍历
key.pollEvents()全部处理
4. 简单可用示例(监听当前目录下新文件)
以下代码片段可直接运行验证:
Path dir = Paths.get(".");
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
System.out.println("开始监听 " + dir.toAbsolutePath() + " 中的文件新增...");
while (true) {
WatchKey key = watcher.take(); // 阻塞等待
for (WatchEvent> event : key.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
Path filename = (Path) event.context();
Path fullPath = dir.resolve(filename);
System.out.println("检测到新文件:" + fullPath);
}
}
if (!key.reset()) break; // 注册目录被删除时退出
}
}Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











