当前位置: 首页 > news >正文

java实现文件变动监听

  1. 在文件的内容发生变动时,应用可以感知这种变种,并重新加载文件内容,更新应用内部缓存

  2. 实现

    1. 轮询:定时器Timer,ScheduledExecutorService

    2. 判断文件修改:根据java.io.File#lastModified获取文件的上次修改时间,比对

    3. public class FileUpTest{private long lastTime;private void ttt(){throw new NullPointerException();}@Testpublic void testFileUpdate(){File file = new File("/tmp/alarmConfig");//首先文件的最近一次修改时间戳lastTime = file.lastModified();//定时任务,每秒来判断一下文件是否发生变动,即判断lastModified是否改变ScheduledExecutorService scheduledExcutorService = Executors.newScheduledThreadPool(1);scheduledExecutorService.scheduleAtFixedRate(new Runnable(){@Oveerridepublic void run(){if(file.lastModified() > lastTime){System.out.println("file update! time : "+ file.lastModified());lastTime = file.getlastModified();ttt();}}},0,1,TimeUnit.SECONDS);try{Thread.sleep(100*60);}catch(InterruptedException e){e.printStackTrace();}}
      }
      
    4. 使用这种的,如果定时任务执行过程中遇到发生异常,则后面的任务将不再执行

  3. apache版本

    1. <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
      </dependency>
      
    2. 借助工具中FileAlterationObserver,FileAlterationListener,FileAlterationMonitor三个类实现相关需求

    3. public class PropertiesConfListenerHelper{public static boolean registerConfChangeListener(File file,Function<File,Map<String,AlarmConfig>> func){try{//轮询间隔5秒long interval = TimeUnit.SECONDS.toMillis(5);//因为监听是以目录为单位进行的,所以这里直接获取文件的根目录File dir = file.getParentFile();//创建一个文件观察期用于过滤FileAlterationObserver observer = new FileAlterationObserver(dir,FileFilterUtils.and(FileFilterUtils.fileFileFilter(),FileFilterUtils.nameFileFilter(file.getName())));//设置文件变化监听器observer.addListener(new MyFileListener(func));FileAlterationMonitor monitor = new FileAlterationMonitor(interval,observer);monitor.start();return true;}catch(Exception e){log.error("register properties change listener error! e:{}",e);return false;}}static final class MyFileListener extends FileAlterationListenerAdaptor{private Function<File,Map<String,AlarmConfig>> func;public MyfileListener(Function<File,Map<String,AlarmConfig>> func){this.func = func;}@Overridepublic void onFileChange(File file){Map<String,AlarmConfig> ans = func.apply(file);//如果加载失败,打印一条日志log.warn("PropertiesConfig changed ! reload ans: {}",ans);}}
      }
      
    4. 介绍

      1. 这个文件监听,是以目录为根源,可以设置过滤器,来实现对应文件变动的监听
      2. 上面的registerConfChangeListener方法,传入的file是具体的配置文件,因此构建参数的时候,拿到目录,拿到文件名作为过滤
      3. 第二个参数是jdk1.8语法,其中为具体的读取配置文件内容,并影射为对应的实体对象
      4. 如果func方式执行时,抛出了一场,程序失败,不在运行
  4. JDK版本

    1. JDK1.7提供了一个WatchService,可以用来实现文件变动的监听

    2. @Test
      public void testFileUpWather() throws IOException{//监听必须是目录Path path = Paths.get("/tmp");WatchService watcher = FileSystems.getDefault().newWatchService();path.register(watcher,ENTRY_MODIFY);new Thread(() ->{try{while(true){WatchKey key = watcher.take();for(WatchEvent<?> event : key.pollEvents()){if(event.kind() == OVERFLOW){                        // 实践可能lost or discardedcontinue}Path fileName = (Path)event.context();System.out.println("文件更新:"+fileName);}if(!key.reset()){//重设WatchKeybreak}}}catch(Exception e){e.printStackTrace();}}).start();try{Thread.sleep(1000* 60 * 10);}catch(InterruptedException e){e.printStackTrace();}
      }
      
    3. 千万不要在定时任务或者文件变动的回调方法中抛出异常

    4. 为了避免异常断开情况,一个是可以做的实现借助EventBus的异步消息通知机制来实现,当文件变动之后,发送一个消息即可,然后在具体的重新加载文件内容的方法上,添加一个@Subscribe注解即可,这样既实现了解耦,也避免了一场导致的服务异常


http://www.mrgr.cn/news/54765.html

相关文章:

  • 【Android_14】ACodec-OMX跨IPC的一些类
  • vue3使用ref动态获取组件,并对动态表单组件进行校验
  • 计算机网络——第三章 数据链路层
  • 博客|基于springBoot的精简博客系统设计与实现(附项目源码+论文+数据库)
  • 中国信通院联合中国电促会开展电力行业企业开源典型实践案例征集
  • vulnhub靶场之JOY
  • vulnhub靶场之JOY
  • 提示词高级阶段学习day2.1-在提示词编写中对{}的使用教程
  • 卷积神经网络
  • R语言中的stat_compare_means():如何解决anova目标对象的方法问题
  • 我对需求分析的理解
  • DockerCompose快速部署Java项目、nginx前端和mysql数据库到centos虚拟机
  • ES6 中函数参数的默认值
  • protobuf 未知字段的获取
  • gc cr/current block 2-way
  • 【MySQL】内外连接
  • 2024年深圳福田区第十二届职工技能大比武职业技能竞赛圆满收官
  • Vue-router 路由守卫执行流程图
  • 光纤光学的基本方程
  • 【MySQL】:库的操作
  • 【力扣打卡系列】滑动窗口与双指针(接雨水)
  • 【Maven】一篇带你了解Maven项目管理工具
  • int argc, char *argv[]
  • 6.C++经典实例-计算给定范围内的素数(质数)
  • SLACC Simion-based Language Agnostic Code Clones
  • 基于STM32的超声波流量计设计