背景
有时候需要在某个文件发生变化时,做出相应的一些操作。例如,想在xml文件、properties属性文件等发生变化时,重新解析文件中的内容等。这时可以设计一个文件看门狗,不断检测文件是否发生了变化,从而做出相应的操作。
设计方法
间隔一定的时间,获取指定文件的修改的时间戳,和上一次修改的时间戳作对比,不相等则表示文件发生了变化。
实现代码
FileWatchdog抽象类:
public abstract class FileWatchdog extends Thread {
private static final Logger logger = LoggerFactory.getLogger(FileWatchdog.class);
public static final long DEFAULT_INTERVAL = 30000;
private String filename;
private File file;
/**
* 检测的间隔时间
*/
private long interval;
/**
* 文件的上一次修改时间戳
*/
private long prevModified;
private boolean warnedAlready;
private volatile boolean interrupted;
protected FileWatchdog(String filename) {
this(filename, DEFAULT_INTERVAL);
}
protected FileWatchdog(String filename, long interval) {
this.interval = interval;
this.filename = filename;
this.file = new File(filename);
this.prevModified = this.file.lastModified();
setDaemon(true); // 设置为守护线程,主线程停止后立即停止
}
/**
* 文件发生变化时触发该方法
*/
protected abstract void doOnChange();
public void run() {
while (!interrupted) { // 每间隔interval毫秒检测一次
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
// do nothing
}
check();
}
}
private void check() {
boolean fileExists;
try {
fileExists = file.exists();
} catch (SecurityException e) {
logger.warn("Was not allowed to read check file existance, file:[].", filename);
interrupted = true;
return;
}
if (fileExists) { // 文件存在时对比时间戳
long lastModified = file.lastModified();
if (lastModified > prevModified) {
prevModified = lastModified;
doOnChange(); // 文件发生变化,执行对应的操作
warnedAlready = false;
}
} else {
if (!warnedAlready) {
logger.warn("[] does not exist.", filename);
warnedAlready = true;
}
}
}
/**
* 停止文件看门狗
*/
public void shutdown() {
interrupted = true;
try {
interrupt();
} catch (Exception e) {
// do nothing
}
}
}
XmlWatchdog子类:
public class XmlWatchdog extends FileWatchdog {
protected XmlWatchdog(String filename) {
super(filename);
}
public XmlWatchdog(String filename, long interval) {
super(filename, interval);
}
@Override
protected void doOnChange() {
// 相应的操作,例如重新解析xml等等
// ...
}
}
主线程调用:
XmlWatchdog xmlWatchdog = new XmlWatchdog("D:\\abc.xml");
xmlWatchdog.start();
// 主线程的其它操作
// ...