java filesystemwatcher在以高频率写入文件时,在所有文件都被写入之前不会捕获文件创建事件

jfgube3f  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(332)

我正在尝试使用spring boot devtools filewatch包的filesystemwatcher监视目录上的filecreated事件在文件被写入时捕获created事件是可以正常工作的。但是我在编写高频文件时遇到了一个问题。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;
        }
    }
}
0mkxixxg

0mkxixxg1#

我已通过存储文件的文件夹找到根本原因,该文件夹将被writer进程锁定。对于高频,它将被锁定,直到写入程序完成。所以,我把代码改成了另一种方式。我使用common.io包来监视文件夹,只锁定正在写入的文件而不锁定文件夹。因此,我的writer应用程序和listener应用程序可以并行工作

相关问题