Java使用WatchService监控文件内容变化的示例
作者:Chown 发布时间:2023-02-15 10:10:19
标签:java,监控,文件
场景
系统实现中经常需要能够感知配置文件的变化,然后及时更新上下文。
实现方案
自己起一个单独线程,定时加载文件,实现较简单,但是无法保证能够实时捕捉文件变化,同时耗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
来源:https://zhuanlan.zhihu.com/p/29089171


猜你喜欢
- 一 前言redis在分布式应用十分广泛,本篇文章也是互联网面试的重点内容,读者至少需要知道为什么需要分布式锁,分布式锁的实现原理,分布式锁的
- 底座的状态跟充电状态类似,很多底座提供充电功能(座充).底座状态同样使用sticky Intent广播。可以查询设备是否插入底座,哪种底座。
- 混淆器通过删除从未用过的代码和使用晦涩名字重命名类、字段和方法,对代码进行压缩,优化和混淆。结果是一个比較小的.apk文件,该文件比較难进行
- 不同的浏览器会把cookie文件保存在不同的地方以下是C# WebBrowser控件cookies的存放路径C:\Users\{你的帐号名}
- 今天是解决报错的一天,首先在操作Springboot中的时候,有些朋友的yml显示的不是绿叶的图标,或者是配置了之后不生效的问题。第一个解决
- 程序可分为三部分:头文件:包含结构声明和使用这些结构的函数的原型源代码文件:包含与结构有关的函数的代码源代码文件:包含调用与结构相关的函数代
- Java类加载器1、BootClassLoader: 用于加载Android Framework层class文件。2、PathClassLo
- 一、Unity Shader基础1、创建和使用Shader在Unity中Shader一般由两种用途:指定给材质,用于物理渲染;指定给脚本,用
- XuLIeHua类库using System;using System.Collections; using System.Co
- 最近公司项目中有一个类似滴滴出行填写验证码的弹框,下面是我撸出来的效果: 中间的那个输入密码的6个框框其实就是用shape画的背景
- 原本计划这一篇来总结JSP,由于JSP的内容比较多,又想着晚上跑跑步减减肥,所以今天先介绍Filter以及它的使用举例,这样的话还有些时间可
- 前言:这两天在整WebApi的服务,由于调用方是Android客户端,Android开发人员也不懂C#语法,API里面的接口也不能直接给他们
- 本文参考于《深入理解Java虚拟机》内存分配与回收策略Java技术体系的自动内存管理,最根本的目标是自动化地解决两个问题:自动给对象分配内存
- 前言众所周知,Struts2是个非常优秀的开源框架,我们能用Struts2框架进行开发,同时能快速搭建好一个Struts2框架,但我们是否能
- @Autowired注解注入的xxxMapper报错项目场景Mybatis-Plus测试问题描述在Mybatis-Plus场景的测试中发现,
- FTP简介文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,它工作在 OSI 模
- C#是一种编译型的语言,程序执行,首先要经过编译器编译,如何让C#像一种脚本一样,在要执行的时候,进行编译,这里,我们可以用Microsof
- 1、@Component 是用在类上的@Component public class Student { private String na
- 本文章使用C#编程,制作一个端口扫描器,能够扫描本机有哪些端口开放了,并显示出来,分别使用单线程和多线程进行了比较。编译软件:Visual
- 环境变量这个概念不陌生, 就是操作系统的环境变量。系统变量就是java本身维护的变量。 通过 System.getProperty 的方式获