欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java使用WatchService监控文件内容变化的示例

程序员文章站 2024-04-01 23:41:58
场景 系统实现中经常需要能够感知配置文件的变化,然后及时更新上下文。 实现方案 自己起一个单独线程,定时加载文件,实现较简单,但是无法保证能够实时捕捉文件变化...

场景

系统实现中经常需要能够感知配置文件的变化,然后及时更新上下文。

实现方案

  • 自己起一个单独线程,定时加载文件,实现较简单,但是无法保证能够实时捕捉文件变化,同时耗cpu
  • 使用commons-io中的 filealterationobserver,思想和上面类似,对比前后文件列表的变化,触发对应事件
  • jdk 1.7提供的watchservice,利用底层文件系统提供的功能

使用 watchservice

watchservice用来监控一个目录是否发生改变,但是可以通过 watchevent 上下文定位具体文件的变化。具体使用过程中要注意以下两点:

  • 文件改变可能会触发两次事件(我的理解:文件内容的变更,元数据的变更),可以通过文件的时间戳来控制
  • 在文件变化事件发生后,如果立即读取文件,可能所获内容并不完整,建议的做法判断文件的 length > 0
// 监控文件的变化,重新加载
executor.submit(new runnable() {
  @override
  public void run() {
    try {
      final path path = filesystems.getdefault().getpath(getmonitordir());
      system.out.println(path);
      final watchservice watchservice = filesystems.getdefault().newwatchservice();
      final watchkey watchkey = path.register(watchservice, standardwatcheventkinds.entry_modify);
      while (true) {
        final watchkey wk = watchservice.take();
        for (watchevent<?> event : wk.pollevents()) {
          final path changed = (path) event.context();
          path absolute = path.resolve(changed);
          file configfile = absolute.tofile();
          long lastmodified = configfile.lastmodified();
          logger.info(lastmodified + "----------------");
          // 利用文件时间戳,防止触发两次
          if (changed.endswith(getlicensename()) && lastmodified != last_mod && configfile.length > 0) {
            logger.info("----------------- reloading -----------------");
            last_mod = lastmodified; // 保存上一次时间戳
            updated = true; // 设置标志位
          }
        }

        if (updated) {
          reloadfile(); // 重新加载
        }
        // reset the key
        boolean valid = wk.reset();
        if (!valid) {
          logger.error("watch key invalid!");
        }
      }
    } catch (exception e) {
      logger.error("");
    }
  }
});

参考

watching a directory for changes

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。