背景:在实际环境部署构成中,因为特殊网络环境因素,有不少服务器之间的网络都是单向的,不能互相访问的,只有经过特定技术手段作到文件的单项摆渡,这就须要在两台服务器上分别写序列化程序和反序列化程序,这里不记录序列化的内容,记录反序列化程序中的文件监控内容。java
一、文件监控方式一:java的文件监控有两种方式,方法一:java7提供的 WatchService,可是这个方法有一些问题存在如下问题:服务器
a.当文件修改的时候,会收到两次通知,这个问题须要经过本身写代码去解决网络
b.不能监控子目录下的文件变化ide
c.没法对监控文件进行过滤,只监控本身感兴趣的文件spa
二、文件监控方式二:commons-io(原理采用监控者模式和定时刷新监控文件夹),项目中实际使用的方式。操作系统
代码以下:debug
/** * 目录监听器 * * @return */ @Bean public FileAlterationMonitor fileAlterationMonitor(@Autowired DirectoryWatchService directoryWatchService, @Autowired FileFilter fileFilter) { //监控器 100 监控刷新时间 FileAlterationMonitor monitor = new FileAlterationMonitor(100);
// 多个文件夹监控,须要add多个观察者 for (String path : directoryPath) { log.info("监听目录:{}",path);
//对某个路径的观察者 FileAlterationObserver observer = new FileAlterationObserver(path, fileFilter); // 增长文件过滤,符合文件后缀的文件才进行处理,防止操做系统中生成的临时文件没法处理 //添加监听事件响应,与path无关,rsync同步须要 observer.addListener(directoryWatchService); //将观察者添加到监控器 monitor.addObserver(observer); } return monitor; }
目录监听服务code
@Component @Slf4j public class DirectoryWatchService extends FileAlterationListenerAdaptor { @Override public void onStart(FileAlterationObserver observer) { log.debug("开始对目录:{}进行监听", observer.getDirectory().getPath()); } @Override public void onDirectoryCreate(File directory) { log.info("目录:{}建立", directory.getPath()); } @Override public void onDirectoryChange(File directory) { log.info("目录:{}改变", directory.getPath()); } @Override public void onDirectoryDelete(File directory) { log.info("目录:{}被删除", directory.getPath()); } @Override public void onFileCreate(File file) { log.info("文件:{}建立", file.getPath()); // TODO } @Override public void onFileChange(File file) { log.info("文件:{}改变", file.getPath()); } @Override public void onFileDelete(File file) { log.info("文件:{}删除", file.getPath()); } @Override public void onStop(FileAlterationObserver observer) { log.debug("中止目录{}监听", observer.getDirectory().getPath()); super.onStop(observer); } }
文件过滤器server
public class BchtFileFilter implements FileFilter { @Override public boolean accept(File pathname) { if(pathname.getPath().endsWith(".data") || pathname.getPath().endsWith(".DATA")){ return true; } return false; } }