当前位置: 首页 > 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.lryc.cn/news/465371.html

相关文章:

  • Maven的使用
  • C++开发进阶1:C++编程命名规范
  • Android 图片相识度比较(pHash)
  • Gitlab 完全卸载–亲测可行
  • gitlab操作和管理
  • ctfshow-web入门-反序列化(web254-web258)
  • repo 命令大全详解(第十一篇 repo init)
  • ComfyUI | 全新ComfyUI前端操作指南:提升你的工作速度!
  • nginx解决非人类使用http打开的443,解决网安漏扫时误扫443端口带来的问题
  • 黑马 | Reids | 基础篇
  • SAP-换登录界面图片
  • 移动 Web核心笔记(二)
  • MySQL创建和管理表
  • 【从零开始的LeetCode-算法】910. 最小差值 II
  • 周报 | 24.10.14-24.10.20文章汇总
  • Codeforce 980 Div2 A-D 题解
  • 一次代码优化的过程
  • 多线程的学习(1)
  • PyCharm借助MobaXterm跳板机连接服务器
  • 计算机毕业论文基于Android 的签到系统设计与实现
  • 量化学习-02
  • SAP_MM模块-设置业务合作伙伴类型字段必输(多种方案)
  • STM32平台上实现串口接收不定长数据-实际项目中应用
  • AWD入门
  • T3矩阵看功率
  • VLMEvalKit多模态大模型评测工具源码解析
  • 将 Docker 安装到指定目录
  • 哪些企业需要部署SD-WAN?
  • 通信基站类型、频段与网络标准
  • Java IO教程之Java 文件一口气讲完!( *︾▽︾)