SpringBoot中实现文件监听并在数据库中保存对该文件的操作记录
实现方式:org.apache.commons.io.monitor.FileAlterationObserver
1.创建一个项目启动时就启动的方法,来开启监听(实现ApplicationRunner接口,重写run方法)
/**
* 项目启动时执行的方法
* @author daiguojun
*/
@Component
@Slf4j
public class MyApplicationRunner implements ApplicationRunner {
//读取配置文件中了文件路径 拿到要监听的文件夹
@Value("${file.path}")
private String path;
@Override
public void run(ApplicationArguments args) {
try {
// 构造观察类主要提供要观察的文件或目录,当然还有详细信息的filter
FileAlterationObserver observer = new FileAlterationObserver(new File(path));
// 构造收听类
FileListener listener = new FileListener();
// 为观察对象添加收听对象
observer.addListener(listener);
// 配置Monitor,第一个参数单位是毫秒,是监听间隔;第二个参数就是绑定我们之前的观察对象。
FileAlterationMonitor fileMonitor = new FileAlterationMonitor(10000, new FileAlterationObserver[] { observer });
// 启动监听
fileMonitor.start();
} catch (Exception e) {
log.info("启动失败!");
e.printStackTrace();
}
}
}
2.新建类,重写FileAlterationListener接口
/**
* @Author: daiguojun
* @CreateDate: 2021/3/31 16:52
* @Description: 监听文件的创建删除修改 (并在数据库中保存相关的记录)
*/
@Slf4j
@Component
public class FileListener implements FileAlterationListener {
private Dao dao;
@Override
public void onStart(FileAlterationObserver fileAlterationObserver) {
orderDao = SpringUtil.getBean(dao.class);
}
@Override
public void onDirectoryCreate(File file) {
log.info(file.getPath()+"---该路径下新建了一个文件夹");
}
@Override
public void onDirectoryChange(File file) {
log.info(file.getPath()+"--文件夹发生改变");
}
@Override
public void onDirectoryDelete(File file) {
log.info(file.getPath()+"---文件夹被删除");
}
@Override
public void onFileCreate(File file) {
//把被创建的文件信息存放到数据库
log.info("文件被创建:"+file.getPath());
//数据入库
try {
Object o = dao.selectFileInfo(file.getPath());
if(o == null){
long l = file.lastModified();
String id = UUID.randomUUID().toString().replace("-","");
Date date = new Date(l);
String filePath = file.getPath();
String fileName = file.getName();
long length = file.length();
String fileSize = String.valueOf(length);
orderDao.insertFileInfo(id,date,date,filePath,fileName,fileSize);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFileChange(File file) {
log.info("文件发生改变"+file.getPath());
//记录文件在什么时间发生改变
try {
String name = file.getPath();
long l = file.lastModified();
Date date = new Date(l);
String time = DateUtil.formatDateTime(date, "yyyy-MM-dd HH:mm:ss");
orderDao.updateOrderFileInfo(time,name);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFileDelete(File file) {
log.info("文件被删除"+file.getPath());
//记录文件什么时间被删除同时清除数据库中存在的记录
try {
Object o = dao.selectInfo(file.getPath());
if(o != null){
dao.deleteByFileName(file.getPath());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onStop(FileAlterationObserver fileAlterationObserver) {
//监听结束时执行的方法
}
}
注意: 因为实现了FileAlterationListener接口,所以通过Autowried的方式注入dao层会注入失败。
解决办法:可以从Spring容器中直接或去bean对象,上文通过springUtil的getBean方法实现。
监听某一文件夹可能会加重这个文件夹的压力,尤其是如果这个文件夹在共享盘,可能会影响共享盘的读取速率