一、目的
之前的集群文件同步,在集群启动完成同步之后,由于同步依靠缓存集群分发,手动的文件操作无法触发缓存同步更新,因此无法支持在一台节点手动添加/删除/修改文件同步到其它节点。根据需求,需要在手动操作文件使用刷新按钮同步到各个节点;
二、方案
参考commons-io的文件扫描功能,定时比较文件FileEntry,能够及时感知到文件夹和文件的创建、修改、删除,并触发监听器做相应操作;由于commons-io仅支持本地文件系统,因此进行了修改和扩展,使其能够支持不同的存储;
a、解藕和File的绑定,全部使用路径,配合ResourceIOUtils和ResourceRepository来完成文件和文件夹变化的判断;
b、默认使用四个纬度的变化来判断文件及文件的变化类型:是否存在、是否是路径、上次修改时间、文件的大小,见ResourceEntry:
public boolean refresh(final String path) {
//原始值
final boolean origExists = exists;
final long origLastModified = lastModified;
final boolean origDirectory = directory;
final long origLength = length;
//刷新值
name = ResourceIOUtils.getName(path);
exists = ResourceIOUtils.exist(path);
directory = exists && ResourceIOUtils.isDirectory(path);
lastModified = exists ? ResourceIOUtils.lastModified(path) : 0;
length = exists && !directory ? ResourceIOUtils.getLength(path) : 0;
//比较返回是否变化
return exists != origExists ||
lastModified != origLastModified ||
directory != origDirectory ||
length != origLength;
}
如果存储不支持上述的refresh方式,需要继承并重写refresh方法完成文件或文件夹变化的判断;
3、自动检查的方式为用一个线程轮训扫描,手动需要触发运行的接口;
三、使用
//创建观察者
ResourceAlterationObserver observer = new ResourceAlterationObserver("reportlets");
//添加事件监听
observer.addListener(new BaseResourceAlterationListener() {
@Override
public void onStart(ResourceAlterationObserver observer) {
System.out.println("start...");
}
@Override
public void onDirectoryCreate(String directory) {
System.out.println("DirectoryCreate: " + directory);
}
@Override
public void onDirectoryChange(String directory) {
System.out.println("DirectoryChange: " + directory);
}
@Override
public void onDirectoryDelete(String directory) {
System.out.println("DirectoryDelete: " + directory);
}
@Override
public void onFileCreate(String file) {
System.out.println("FileCreate: " + file);
}
@Override
public void onFileChange(String file) {
System.out.println("FileChange: " + file);
}
@Override
public void onFileDelete(String file) {
System.out.println("FileDelete: " + file);
}
@Override
public void onStop(ResourceAlterationObserver observer) {
System.out.println("stop");
}
});
//创建监视器
//自动模式下,设置间隔时间为1000ms
ResourceAlterationMonitor monitor = new ResourceAlterationMonitor(1000, observer);
//手动模式设置时间为-1
//ResourceAlterationMonitor monitor = new ResourceAlterationMonitor(-1, observer);
//添加观察者
monitor.addObserver(observer);
try {
//开始执行
//interval == -1时,运行此方法仅执行一次
//monitor.runOnce();
//interval > 0 时用start开始定时扫描
monitor.start();
} catch (Exception e) {
e.printStackTrace();
}