Spring Boot 监听文件、文件夹

背景

项目中有需要监听文件、文件夹的需求,以便在文件、文件夹发生变化时出发相应的业务流程。这里使用Spring Boot + Apache Commons IO方案。
另外,Apache Commons IO涉及到多线程的应用,项目中应指定线程池的相关配置,参考Spring Boot 线程池配置

步骤

  1. 添加依赖

Gradle: buidle.gradle

compile('commons-io:commons-io:2.6')

Maven: pom.xml

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
  1. 设置监听器
public class FileListener extends FileAlterationListenerAdaptor {

    // 声明业务服务
    private ListenerService listenerService;

    // 采用构造函数注入服务
    public FileListener(ListenerService listenerService) {
        this.listenerService = listenerService;
    }

    // 文件创建执行
    @Override
    public void onFileCreate(File file) {
    }

    // 文件创建修改
    @Override
    public void onFileChange(File file) {
        // 触发业务
        listenerService.doSomething();
    }

    // 文件创建删除
    @Override
    public void onFileDelete(File file) {
    }

    // 目录创建
    @Override
    public void onDirectoryCreate(File directory) {
    }

    // 目录修改
    @Override
    public void onDirectoryChange(File directory) {
    }

    // 目录删除
    @Override
    public void onDirectoryDelete(File directory) {
    }


    // 轮询开始
    @Override
    public void onStart(FileAlterationObserver observer) {
    }

    // 轮询结束
    @Override
    public void onStop(FileAlterationObserver observer) {
    }
}
  1. 添加监听器工厂
@Component
public class FileListenerFactory {

    // 设置监听路径
    private final String monitorDir = "/tmp/monitorTest";

    // 设置轮询间隔
    private final long interval = TimeUnit.SECONDS.toMillis(1);

    // 自动注入业务服务
    @Autowired
    private ListenerService listenerService;

    public FileAlterationMonitor getMonitor() {
        // 创建过滤器
        IOFileFilter directories = FileFilterUtils.and(
                FileFilterUtils.directoryFileFilter(),
                HiddenFileFilter.VISIBLE);
        IOFileFilter files = FileFilterUtils.and(
                FileFilterUtils.fileFileFilter(),
                FileFilterUtils.suffixFileFilter(".log"));
        IOFileFilter filter = FileFilterUtils.or(directories, files);

        // 装配过滤器
        // FileAlterationObserver observer = new FileAlterationObserver(new File(monitorDir));
        FileAlterationObserver observer = new FileAlterationObserver(new File(monitorDir), filter);

        // 向监听者添加监听器,并注入业务服务
        observer.addListener(new FileListener(listenerService));

        // 返回监听者
        return new FileAlterationMonitor(interval, observer);
    }
}
  1. 使用
    这里以SpringBoot自启动任务为例,在应用启动后开始监听目标文件夹。由于监听器在独立的线程中执行,一旦异常发生将导致线程退出,所以如果希望监听线程不中断,应在线程中捕获所有异常。
@Component
public class FileListenerRunner implements CommandLineRunner {

    @Autowired
    private FileListenerFactory fileListenerFactory;

    @Override
    public void run(String... args) throws Exception {
        // 创建监听者
        FileAlterationMonitor fileAlterationMonitor = fileListenerFactory.getMonitor();
        try {
            // do not stop this thread
            fileAlterationMonitor.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

推荐阅读更多精彩内容