导入maven依赖

<dependency>
  <groupId>net.contentobjects.jnotify</groupId>
  <artifactId>jnotify</artifactId>
  <version>0.94</version>
</dependency>

Jnotify底层调用的关键部分是C语言开发的,所以需要在java.library.path中加入jnotify_64bit.dll(64位 Windows)或者libjnotify.so(linux)动态库,jni库的位置在jnitify-0.94.jar的META-INF的native文件夹中。

使用方法

实现JNotifyAdapter并将其传递给JNotify的addWatch方法开始监听。


import lombok.Getter;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyException;
import net.contentobjects.jnotify.JNotifyListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.LinkedBlockingQueue;

public abstract class AbstractMonitor implements Monitor, JNotifyListener {

    private static final Logger log = LoggerFactory.getLogger(AbstractMonitor.class);
    @Getter
    private final Map<String, Integer> pathToWdMap = new HashMap<>();
    @Getter
    private final Map<Integer, String> wdToPathMap = new HashMap<>();
    private final int mask;
    protected final BlockingQueue<MonitorResult> queue = new LinkedBlockingQueue<>();

    public AbstractMonitor(int mask) {
        this.mask = mask;
    }

    @Override
    public int watch(String path, boolean watchSubtree) throws JNotifyException {
        if (pathToWdMap.containsKey(path)) {
            return pathToWdMap.get(path);
        }
        log.info("Watching path {}", path);
        int wd = JNotify.addWatch(path, mask, watchSubtree, this);
        pathToWdMap.put(path, wd);
        wdToPathMap.put(wd, path);
        return wd;
    }

    @Override
    public void unwatch(int wd) throws JNotifyException {
        JNotify.removeWatch(wd);
        String path = wdToPathMap.remove(wd);
        pathToWdMap.remove(path);
        log.info("Unwatching path {}", path);
    }

    @Override
    public MonitorResult take() throws InterruptedException {
        return queue.take();
    }

    protected boolean offer(MonitorResult monitorResult) {
        return queue.offer(monitorResult);
    }

}