Java文件看门狗,检测文件是否发生变化

背景

有时候需要在某个文件发生变化时,做出相应的一些操作。例如,想在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();
// 主线程的其它操作
// ...
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值