我正在尝试使用Spring boot devtools filewatch包的FileSystemWatcher监视目录上的文件创建事件当catch在写入文件时创建事件时,它可以正常工作。但是我在写高频率的文件时遇到了一个问题FileSystemWatcher将等待所有文件被写入,然后为每个文件触发创建的事件。
所以,我希望FileSystemWatcher在写入每个文件时都会触发创建的事件,而不是等到所有文件都被写入后再触发事件。我该怎么做。这是我的代码:
- 监视配置
@Configuration
public class FileWatchingConfiguration {
private Logger logger = LoggerFactory.getLogger(FileWatchingConfiguration.class);
@Value("${application.scope}")
private String appScope;
@Autowired
DataFileChangeListener dataFileChangeListener;
@Bean
public FileSystemWatcher destDataWatcher(){
String folderPath = appScope.equalsIgnoreCase("external") ? Utils.getSyncFolderPath(Constants.DIR_TYPE.EXT_DEST_DATA) : Utils.getSyncFolderPath(Constants.DIR_TYPE.INT_DEST_DATA);
logger.info("Data Watcher folder path watching change " + folderPath );
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(true, Duration.ofMillis(1000L), Duration.ofMillis(500L));
fileSystemWatcher.addSourceDirectory(new File(folderPath));
fileSystemWatcher.addListener(dataFileChangeListener);
fileSystemWatcher.start();
logger.info("dest Data fileSystemWatcher");
return fileSystemWatcher;
}
@PreDestroy
public void onDestroy() throws Exception {
destDataWatcher().stop();
}
}
这是我的onchange事件实现:
@Component
public class LogsFileChangeListener implements FileChangeListener {
private Logger logger = LoggerFactory.getLogger(LogsFileChangeListener.class);
@Autowired
RabbitMQService rabbitMQService;
@Value("${application.scope}")
private String appScope;
@Value("${residents.rabbitmq.listener.ext.sync.exchange}")
private String extSyncExchange;
@Value("${residents.rabbitmq.listener.int.sync.exchange}")
private String intSyncExchange;
@Value("${residents.rabbitmq.listener.file.create.routingKey}")
private String routingKey;
@Override
public void onChange(Set<ChangedFiles> changeSet) {
for(ChangedFiles cfiles : changeSet){
for(ChangedFile cfile : cfiles){
if(cfile.getType().equals(ChangedFile.Type.ADD) || cfile.getType().equals(ChangedFile.Type.MODIFY) && !isLocked(cfile.getFile().toPath())){
String fileName = cfile.getFile().getName();
logger.info("Operation: " + cfile.getType()
+ " On Sync Data file: "+ fileName + " is done");
RabbitMessageModel rabbitMessageModelLog = new RabbitMessageModel();
rabbitMessageModel.setFileName(fileName);
rabbitMessageModel.setFolderPath(Utils.getSyncFolderPath(appScope.equalsIgnoreCase("external") ? Constants.DIR_TYPE.EXT_DEST_DATA : Constants.DIR_TYPE.INT_DEST_DATA));
rabbitMQService.send(rabbitMessageModelLog,routingKey, appScope.equalsIgnoreCase("external") ? extSyncExchange : intSyncExchange);
}
}
}
}
private boolean isLocked(Path path) {
try (FileChannel ch = FileChannel.open(path, StandardOpenOption.WRITE); FileLock lock = ch.tryLock()) {
return lock == null;
} catch (IOException e) {
return true;
}
}
}
我已经找到了存储文件的文件夹被写入程序锁定的根本原因。对于高频,它将被锁定,直到写入程序完成。因此,我将代码更改为另一种方式。我使用common.io包来查看文件夹,只锁定正在写入的文件而不锁定文件夹。因此,我的编写器应用程序和侦听器应用程序可以并行工作