有的时候,可能需要在后台监听服务器上某个目录的变化。比如,往某个目录上传一些文件,后台监听到这些新增的文件后,做一些处理。
apache commons-io 包中的 FileAlterationListenerAdaptor 就是用来实现这个监听功能的。
springboot工程启动时开启监听
要实现监听功能,那么在工程启动时,就要开启监听。这可以通过实现 ApplicationRunner 接口,并重新它的 run() 方法来实现。
/** * ApplicationRunner 是一个 springboot 提供的接口; * 实现它,并重写 run() 方法,那么在项目启动时,该 run() 方法便会自动执行。 */ @Component public class FileListenerConfig implements ApplicationRunner { @Override public void run(ApplicationArguments args) { // 根目录 String rootPath = "E:\\monitor\\"; // 根目录中需要监控的目录列表 String[] monitorDirList = "test1,test2".split(","); // 观察者(Observer)列表 FileAlterationObserver[] observers = new FileAlterationObserver[monitorDirList.length]; for (int i = 0; i < monitorDirList.length; i++) { String monitorPath = rootPath + monitorDirList[i]; // 创建“文件变更观察者”,每一个需要监控的目录,都对应一个观察者(Observer) FileAlterationObserver observer = new FileAlterationObserver(monitorPath); observer.addListener(new MyFileListener(monitorPath)); observers[i] = observer; } // 创建文件变化监听器,构造函数中支持传入多个观察者Observer long interval = TimeUnit.MILLISECONDS.toMillis(1000L); // 轮询间隔1秒 FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observers); try { // 开启监控,会另起线程,且会一直运行 monitor.start(); } catch (Exception e) { System.out.println("目录监听启动异常"); e.printStackTrace(); } } }
具体的监听实现
由于要监听多个目录,所以具体实现中增加了一个字段 monitorDir 来表示具体的目录。
需要继承 FileAlterationListenerAdaptor,并重新它的一系列方法。
当然,根据实际需求来重写方法就行,比如如果只需要监听文件的新增,就可以只重写 onFileCreate(File file) 方法。
@Slf4j @AllArgsConstructor public class MyFileListener extends FileAlterationListenerAdaptor { // 监听的目录 private String monitorDir; @Override public void onStart(FileAlterationObserver observer) { super.onStart(observer); } @Override public void onDirectoryCreate(File directory) { log.info("监控目录:" + monitorDir + ",创建文件夹:" + directory.getPath()); } @Override public void onDirectoryChange(File directory) { log.info("监控目录:" + monitorDir + ",修改文件夹:" + directory.getPath()); } @Override public void onDirectoryDelete(File directory) { log.info("监控目录:" + monitorDir + ",删除文件夹:" + directory.getPath()); } @Override public void onFileCreate(File file) { log.info("监控目录:" + monitorDir + ",创建文件:" + file.getPath()); } @Override public void onFileChange(File file) { log.info("监控目录:" + monitorDir + ",修改文件:" + file.getPath()); } @Override public void onFileDelete(File file) { log.info("监控目录:" + monitorDir + ",删除文件:" + file.getPath()); } @Override public void onStop(FileAlterationObserver observer) { super.onStop(observer); } }
代码就这么些,实现起来还是很方便的。