bigywater.tech
Java · 192

WatchService:Java 如何监听文件变化

WatchService 是怎么监听文件变化的?延迟有多大?事件长什么样?这篇在 macOS 上实测(Linux 上是另一种实现,本篇没有验证),并给出使用时必须注意的 reset 与不递归(文件系统相关的 NIO 篇目在附近)。

PollingWatchService
这台 macOS 上 WatchService 的实现类(轮询)
约 2 秒
创建文件到收到事件的延迟,默认灵敏度与 HIGH 相同
CREATE + DELETE
重命名产生的两个事件

实现与延迟

实测 · 本机执行输出
  WatchService 的实现类:sun.nio.fs.PollingWatchService
  默认灵敏度:创建文件 → 收到事件的延迟(秒)= [1.71, 1.99, 2.00]
  SensitivityWatchEventModifier.HIGH:创建文件 → 收到事件的延迟(秒)= [1.70, 2.00, 2.00]

事件语义

实测 · 本机执行输出
  创建 a.txt 并写入                       → [CREATE(a.txt)]
  覆盖写 a.txt                          → [MODIFY(a.txt)]
  连续追加 3 次                           → [MODIFY(a.txt)]
  重命名 a.txt → b.txt                  → [CREATE(b.txt), DELETE(a.txt)]
  删除 b.txt                           → [DELETE(b.txt)]
  创建子目录 sub                          → [CREATE(sub)]
  在子目录 sub 里创建文件(没有注册 sub)           → [MODIFY(sub)]

key.reset()

实测 · 本机执行输出
  第一次创建:收到 key = true,事件 [CREATE(one)],key.isValid() = true
  没有调用 key.reset() 就再创建一个文件:6 秒内收到事件吗?false(不 reset,这个 key 不会再入队)
  key.reset() 之后:收到 [CREATE(two)]
  删除被监视的目录之后:key.isValid() = false

分步演示

WatchService
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12,macOS(PollingWatchService)
    • 没有验证:Linux 的 inotify 实现及其延迟、Windows 的实现、OVERFLOW 事件的触发、大量文件变化下的事件丢失、符号链接目录、网络文件系统;延迟只测了每种 3 次
    京ICP备2026067502号-1京公网安备11010502063487号