Java文件监控-WatchService了解和使用

前言

前些天在分析性能问题的时候,突然发现一个文件同步的方法严重阻塞了线程。查看代码才发现,每次同步的时候都会全量的获取当前的所有文件。在文件数量较大的场景下,给系统带来的非常严重的阻塞。
找到问题原因就好办了,全量获取文件不是一个长期且行之有效的方式。因此,需要另一种方案来替代全量查询。

WatchService是什么?

WatchService是jdk1.7版本引进的,位于nio包下。
WatchService看作是文件监控器,通过操作系统原生文件系统来运行。
针对单点多appkey的情况,可以注册开启多个监控器。
每个监控器可看作是后台线程,通过监控文件发出的信号来实现监控。

核心方法介绍

WatchService作为文件监控器,支持阻塞和非阻塞两种模式。对应两种模式的方法如下

阻塞(BIO)

WatchKey take():获取下一次的监听结果,没有则一直等待;

非阻塞(NIO)

WatchKey poll():获取下一次监听结果,没有则返回null;
WatchKey poll(long timeout, TimeUnit unit):获取下一次监听结果,最多等待指定时间,没有则返回null;

监听事件

WatchService监听事件宝库及事件丢失,创建,修改,重命名等

StandardWatchEventKinds.OVERFLOW
StandardWatchEventKinds.ENTRY_CREATE
StandardWatchEventKinds.ENTRY_MODIFY
StandardWatchEventKinds.ENTRY_DELETE

WatchService使用

@Component
public class FileWatchDog implements CommandLineRunner {

    Logger logger = LoggerFactory.getLogger(FileWatchDog.class);

    @Override
    public void run(String... args) throws Exception {
        System.out.println("start to watch files changes");
        //实例化WatchService对象
        WatchService watchService = FileSystems.getDefault().newWatchService();
        String url = "C:\\data";
        //构建Path对象
        Path path = Paths.get(url);
		//注册监听事件
        path.register(watchService,
                StandardWatchEventKinds.ENTRY_MODIFY,
                StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE);
		//新建定时任务线程池,仅作为示例使用,实际项目请按标准使用。
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3);
        ScheduledFuture<?> schedule = threadPool.scheduleAtFixedRate(
                () -> {
                    Thread.currentThread().setName("watch-dog-"+Thread.currentThread().getId());
                    //获取监听结果,没有返回null
                    WatchKey key = watchService.poll();
                    
                    if (null == key) {
                        logger.info("暂无文件变化");
                        return;
                    }
                    //利用 key.pollEvents() 方法返回一系列的事件列表
                    for (WatchEvent<?> event : key.pollEvents()) {
                        //得到 监听的事件类型
                        WatchEvent.Kind kind = event.kind();
                        if (kind.name().equals(StandardWatchEventKinds.ENTRY_CREATE.name())) {
                        	//业务逻辑代码
                            System.out.println("监控到文件新增,开始执行同步");
                        }
                        //得到 监听的文件/目录的路径
                        Path pathName = (Path) event.context();
                        logger.info(kind.name() + pathName);
                        //每次的到新的事件后,需要重置监听池
                        key.reset();
                    }
                }, 1000, 10000, TimeUnit.MILLISECONDS
        );


    }
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用JavaWatchService监控文件夹中新增的文件WatchServiceJava NIO 2中的一个特性,它可以监控文件系统的变化,如文件的创建、修改和删除等。 以下是一个简单的示例代码,用于监控指定文件夹中新增的文件: ```java import java.nio.file.*; public class FolderWatcher { public static void main(String[] args) throws Exception { // 获取文件监控服务 WatchService watchService = FileSystems.getDefault().newWatchService(); // 注册要监控文件夹,并设置监控型为新增文件 Path folderPath = Paths.get("/path/to/folder"); folderPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE); // 循环获取文件变化事件 while (true) { WatchKey watchKey = watchService.take(); // 遍历所有文件变化事件 for (WatchEvent<?> event : watchKey.pollEvents()) { // 判断事件型是否为新增文件 if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) { // 获取新增文件的路径 Path filePath = folderPath.resolve((Path) event.context()); System.out.println("New file created: " + filePath); } } // 重置监控,以便下次继续监控 watchKey.reset(); } } } ``` 在上面的示例代码中,我们首先获取了文件监控服务,并注册了要监控文件夹和监控型。然后,我们进入一个无限循环,在循环中不断获取文件变化事件,并判断事件型是否为新增文件。如果是新增文件,则输出文件的路径。最后,我们重置监控以便下次继续监控

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值