1、准备 commons-io 2.0 以上版本Jar包,这里我才用 Maven 库依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
2、实现 FileAlterationListenerAdaptor 的自定义类,用来处理文件变动事件,我这里只是简单实现,可参考
package com.zane.hotupdateFiles;
import java.io.File;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationObserver;
/***
* 文件变动事件处理器类
* @author Zane
* @Time 2019年1月5日 上午11:03:35
*/
public class MyFileListenerAdaptor extends FileAlterationListenerAdaptor{
@Override
public void onFileChange(File file) {
System.out.println("change.............");
super.onFileChange(file);
}
@Override
public void onStart(FileAlterationObserver observer) {
System.out.println("start");
super.onStart(observer);
}
@Override
public void onStop(FileAlterationObserver observer) {
System.out.println("stop");
super.onStop(observer);
}
@Override
public void onDirectoryChange(File directory) {
System.out.println("dir change.........");
super.onDirectoryChange(directory);
}
@Override
public void onDirectoryCreate(File directory) {
System.out.println("dir create.........");
super.onDirectoryCreate(directory);
}
@Override
public void onDirectoryDelete(File directory) {
System.out.println("dir delete.........");
super.onDirectoryCreate(directory);
}
}
3、自己封装的监听器类,构造函数需要给出 监听文件目录,监听文件的类型,事件处理类对象等
package com.zane.hotupdateFiles;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
/***
* 自定义文件监视器,可用来实现热更配置文件/监听文件场景
* @author Zane
* @Time 2019年1月5日 上午10:41:12
*/
public class MyFileAlterationMonitor {
private String path; // 文件夹目录
private String fileSuffix; // 需要监听的文件名后缀
private long interval; // 监听间隔
private static final long DEFAULT_INTERVAL = 10 * 1000; // 默认监听间隔10s
private FileAlterationListenerAdaptor listener; // 事件处理类对象
public MyFileAlterationMonitor(){
this.interval = DEFAULT_INTERVAL;
}
public MyFileAlterationMonitor(String path, String fileSuffix, FileAlterationListenerAdaptor listenerAdaptor){
this.path = path;
this.fileSuffix = fileSuffix;
this.interval = DEFAULT_INTERVAL;
this.listener = listenerAdaptor;
}
public MyFileAlterationMonitor(String path, String fileSuffix, long interval, FileAlterationListenerAdaptor listenerAdaptor) {
this.path = path;
this.fileSuffix = fileSuffix;
this.interval = interval;
this.listener = listenerAdaptor;
}
/***
* 开启监听
*/
public void start() {
if(path==null) {
throw new IllegalStateException("Listen path must not be null");
}
if(listener==null) {
throw new IllegalStateException("Listener must not be null");
}
// 设定观察者,监听.properties文件
FileAlterationObserver observer = new FileAlterationObserver(path,
FileFilterUtils.suffixFileFilter(fileSuffix));
// 给观察者添加监听事件
observer.addListener(listener);
// 开启一个监视器,监听频率是5s一次
// FileAlterationMonitor本身实现了 Runnable,是单独的一个线程,按照设定的时间间隔运行,默认间隔是 10s
FileAlterationMonitor monitor = new FileAlterationMonitor(interval);
monitor.addObserver(observer);
try {
monitor.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void setPath(String path) {
this.path = path;
}
public void setFileSuffix(String fileSuffix) {
this.fileSuffix = fileSuffix;
}
public void setAdaptor(FileAlterationListenerAdaptor listenerAdaptor) {
this.listener = listenerAdaptor;
}
}
最后进行测试
测试代码如下,监听 properties 资源文件夹下的 .properties 文件:
public class Test {
public static void main(String[] args) {
MyFileAlterationMonitor monitor = new MyFileAlterationMonitor(
Test.class.getClassLoader().getResource("properties").getPath(),
".properties",
new MyFileListenerAdaptor());
monitor.start();
}
}
测试结果:
start
stop
start
stop
start
change.............
stop
start
stop
start
stop
start
stop
结果分析:
1、监听器本身会启动一个线程定时处理,相当于一个定时器
2、每次运行时,都会先调用事件监听处理类的 onStart 方法,然后检查是否有变动,并调用对应事件的方法,如 onChange 文件内容改变,检查完后,再调用 onStop 方法,释放当前线程占用的CPU资源,等待下次间隔时间到了被再次唤醒运行。
3、使用该方法,可以实现项目配置文件的热更,以及在需要监控文件的应用场景下使用