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

中小企业网站的主流类型是杭州网站建设|网站设计

中小企业网站的主流类型是,杭州网站建设|网站设计,开发小程序需要备案吗,中网互联网站建设背景 在某些业务场景下#xff0c;我们需要自己实现文件内容变更监听的功能#xff0c;比如#xff1a;监听某个文件是否发生变更#xff0c;当变更时重新加载文件的内容。看似比较简单的一个功能#xff0c;但如果在某些JDK版本下#xff0c;可能会出现意想不到的Bug。本… 背景 在某些业务场景下我们需要自己实现文件内容变更监听的功能比如监听某个文件是否发生变更当变更时重新加载文件的内容。看似比较简单的一个功能但如果在某些JDK版本下可能会出现意想不到的Bug。本篇文章就带大家简单实现一个对应的功能并分析一下对应的Bug和优缺点。初步实现思路 监听文件变动并读取文件简单的思路如下单起一个线程定时获取文件最后更新的时间戳单位毫秒对比上一次的时间戳如果不一致则说明文件被改动则重新进行加载这里写一个简单功能实现不包含定时任务部分的demopublic class FileWatchDemo {/*** 上次更新时间*/public static long LAST_TIME  0L;public static void main(String[] args) throws IOException {String fileName  /Users/zzs/temp/1.txt;// 创建文件仅为实例实践中由其他程序触发文件的变更createFile(fileName);// 执行2次for (int i  0; i  2; i) {long timestamp  readLastModified(fileName);if (timestamp ! LAST_TIME) {System.out.println(文件已被更新  timestamp);LAST_TIME  timestamp;// 重新加载文件内容} else {System.out.println(文件未更新);}}}public static void createFile(String fileName) throws IOException {File file  new File(fileName);if (!file.exists()) {boolean result  file.createNewFile();System.out.println(创建文件  result);}}public static long readLastModified(String fileName) {File file  new File(fileName);return file.lastModified();} }在上述代码中先创建一个文件方便测试然后两次读取文件的修改时间并用LAST_TIME记录上次修改时间。如果文件的最新更改时间与上一次不一致则更新修改时间并进行业务处理。示例代码中for循环两次便是为了演示变更与不变更的两种情况。执行程序打印日志如下文件已被更新1653557504000 文件未更新执行结果符合预期。这种解决方案很明显有两个缺点无法实时感知文件的变动程序轮训毕竟有一个时间差lastModified返回的时间单位是毫秒如果同一毫秒内容出现两次改动而定时任务查询时恰好落在两次变动之间则后一次变动则无法被感知到。第一个缺点对业务的影响不大第二个缺点的概率比较小可以忽略不计JDK的Bug登场 上面的代码实现正常情况下是没什么问题的但如果你使用的Java版本为8或9时则可能出现意想不到的Bug这是由JDK本身的Bug导致的。编号为JDK-8177809的Bug是这样描述的JDK-8177809Bug地址为https://bugs.java.com/bugdatabase/view_bug.do?bug_id8177809这个Bug的基本描述就是在Java8和9的某些版本下lastModified方法返回时间戳并不是毫秒而是秒也就是说返回结果的后三位始终为0。我们来写一个程序验证一下public class FileReadDemo {public static void main(String[] args) throws IOException, InterruptedException {String fileName  /Users/zzs/temp/1.txt;// 创建文件createFile(fileName);for (int i  0; i  10; i) {// 向文件内写入数据writeToFile(fileName);// 读取文件修改时间long timestamp  readLastModified(fileName);System.out.println(文件修改时间  timestamp);// 睡眠100msThread.sleep(100);}}public static void createFile(String fileName) throws IOException {File file  new File(fileName);if (!file.exists()) {boolean result  file.createNewFile();System.out.println(创建文件  result);}}public static void writeToFile(String fileName) throws IOException {FileWriter fileWriter  new FileWriter(fileName);// 写入随机数字fileWriter.write(new Random(1000).nextInt());fileWriter.close();}public static long readLastModified(String fileName) {File file  new File(fileName);return file.lastModified();} }在上述代码中先创建一个文件然后在for循环中不停的向文件写入内容并读取修改时间。每次操作睡眠100ms。这样同一秒就可以多次写文件和读修改时间。执行结果如下文件修改时间1653558619000 文件修改时间1653558619000 文件修改时间1653558619000 文件修改时间1653558619000 文件修改时间1653558619000 文件修改时间1653558619000 文件修改时间1653558620000 文件修改时间1653558620000 文件修改时间1653558620000 文件修改时间1653558620000修改了10次文件的内容只感知到了2次。JDK的这个bug让这种实现方式的第2个缺点无限放大了同一秒发生变更的概率可比同一毫秒发生的概率要大太多了。PS在官方Bug描述中提到可以通过Files.getLastModifiedTime来实现获取时间戳但笔者验证的结果是依旧无效可能不同版本有不同的表现吧。更新解决方案 Java 8目前是主流版本不可能因为JDK的该bug就换JDK吧。所以我们要通过其他方式来实现这个业务功能那就是新增一个用来记录文件版本version的文件或其他存储方式。这个version的值可在写文件时按照递增生成版本号也可以通过对文件的内容做MD5计算获得。如果能保证版本顺序生成使用时只需读取版本文件中的值进行比对即可如果变更则重新加载如果未变更则不做处理。如果使用MD5的形式则需考虑MD5算法的性能以及MD5结果的碰撞概率很小可以忽略。下面以版本的形式来展示一下demopublic class FileReadVersionDemo {public static int version  0;public static void main(String[] args) throws IOException, InterruptedException {String fileName  /Users/zzs/temp/1.txt;String versionName  /Users/zzs/temp/version.txt;// 创建文件createFile(fileName);createFile(versionName);for (int i  1; i  10; i) {// 向文件内写入数据writeToFile(fileName);// 同时写入版本writeToFile(versionName, i);// 监听器读取文件版本int fileVersion  Integer.parseInt(readOneLineFromFile(versionName));if (version  fileVersion) {System.out.println(版本未变更);} else {System.out.println(版本已变化进行业务处理);}// 睡眠100msThread.sleep(100);}}public static void createFile(String fileName) throws IOException {File file  new File(fileName);if (!file.exists()) {boolean result  file.createNewFile();System.out.println(创建文件  result);}}public static void writeToFile(String fileName) throws IOException {writeToFile(fileName, new Random(1000).nextInt());}public static void writeToFile(String fileName, int version) throws IOException {FileWriter fileWriter  new FileWriter(fileName);fileWriter.write(version );fileWriter.close();}public static String readOneLineFromFile(String fileName) {File file  new File(fileName);String tempString  null;try (BufferedReader reader  new BufferedReader(new FileReader(file))) {//一次读一行读入null时文件结束tempString  reader.readLine();} catch (IOException e) {e.printStackTrace();}return tempString;} }执行上述代码打印日志如下版本已变化进行业务处理 版本已变化进行业务处理 版本已变化进行业务处理 版本已变化进行业务处理 版本已变化进行业务处理 版本已变化进行业务处理 版本已变化进行业务处理 版本已变化进行业务处理 版本已变化进行业务处理可以看到每次文件变更都能够感知到。当然上述代码只是示例在使用的过程中还是需要更多地完善逻辑。小结 本文实践了一个很常见的功能起初采用很符合常规思路的方案来解决结果恰好碰到了JDK的Bug只好变更策略来实现。当然如果业务环境中已经存在了一些基础的中间件还有更多解决方案。而通过本篇文章我们学到了JDK Bug导致的连锁反应同时也见证了实践见真知。很多技术方案是否可行还是需要经得起实践的考验才行。赶快检查一下你的代码实现是否命中该Bug往期推荐最简单的6种防止数据重复提交的方法(干货)Spring Cloud OpenFeign 的 5 个优化小技巧IDEA 版 Postman 面世了功能真心强大
http://www.zqtcl.cn/news/138294/

相关文章:

  • 大兴手机网站建设深圳小程序开发公司
  • c 大型网站开发案例电销系统线路
  • 鸿扬家装网站建设谈谈对seo的理解
  • 七米网站建设做网站也分内存大小的吗
  • 丝足网站的建设南宁关键词排名公司
  • 上饶商城网站建设亚马逊海外购官方网
  • 做网站代理商好赚吗高端品牌男鞋有哪些
  • 农产品网站建设及优化项目商务网站建设 视频
  • 北京兼职做网站建设百度app平台
  • 网站建设头部代码网站怎么做咨询
  • 网站运营 网站建设北京公司网站制作要多少钱
  • 郑州看妇科最好的医院是哪里南宁百度seo软件
  • 深圳市住房与建设局实名制网站手机网站打不开被拦截怎么办
  • 公司做网站的价格几千元wordpress 修改页脚
  • 专业网站建设公司在线咨询宁波网站推广公司价格
  • 网站搭建系统都有哪些丽水网站开发
  • 网站设计包含哪些技术外行怎么做网站
  • 网站建设运营知识推广软文平台
  • 营销型网站建设用途网站 文件夹结构
  • 制作网站建设策划方案cosy主题wordpress
  • 网站建设服务联享科技net和cn哪个做网站好
  • 深圳网站制作公司哪家好艺考培训学校
  • 潍坊网站的公司电话html网站开发基础
  • 网站模板样式做地图特效的网站
  • 商标查询官方网站有没有免费找客户的软件
  • 网站开发及服务合同行业网站名称
  • 网站建设费包括什么建筑设计领域
  • 网站建设 信科网络建行网站会员注册用户名
  • 网站建设的什么是开发实施注意什么网站开发实用技术pdf
  • 网站设计的资质叫什么贵阳网站建设咨询