搜索
首页Javajava教程java利用WatchService实时监控某个目录下的文件变化并按行解析实例详解

首先说下需求:通过ftp上传约定格式的文件到服务器指定目录下,应用程序能实时监控该目录下文件变化,如果上传的文件格式符合要求,将将按照每一行读取解析再写入到数据库,解析完之后再将文件改名。

一. 一开始的思路

  设置一个定时任务,每隔一分钟读取下指定目录下的文件变化,如果有满足格式的文件,就进行解析。

     这种方式很繁琐,而且效率低,效率都消耗在了遍历、保存状态、对比状态上了! 而且无法利用OS的很多功能。

 

二. WatchService介绍

1、 该类的对象就是操作系统原生的文件系统监控器!我们都知道OS自己的文件系统监控器可以监控系统上所有文件的变化,这种监控是无需遍历、无需比较的,是一种基于信号收发的监控,因此效率一定是最高的;现在Java对其进行了包装,可以直接在Java程序    中使用OS的文件系统监控器了;

2、 获取当前OS平台下的文件系统监控器:

         i. WatchService watcher = FileSystems.getDefault().newWatchService();

         ii. 从FileSystems这个类名就可以看出这肯定是属于OS平台文件系统的,接下来可以看出这一连串方法直接可以得到一个文件监控器;

  这里暂时不用深入理解这串方法的具体含义,先知道怎么用就行了;

3、 我们都知道,操作系统上可以同时开启多个监控器,因此在Java程序中也不例外,上面的代码只是获得了一个监控器,你还可以用同样的代码同时获得多个监控器;

4、 监控器其实就是一个后台线程,在后台监控文件变化所发出的信号,这里通过上述代码获得的监控器还只是一个刚刚初始化的线程,连就绪状态都没有进入,只是初始化而已;

 

三、实现过程

  其实就是在初始化的时候创建一个线程,然后用watchService实时监控该目录下文件变化,如果有满足条件文件加进来,就按照约定的格式解析文件再写入数据库,详细步骤如下!

  1、web.xml监听器配置文件监控监听器  

930406f08da8ee4a2ff134b688d29d1dcd65b3a4eec0dfd2b520f594bda16a0f75d9475f58d50d678ef97bf7ae35ef75c13d9669d2c8f87a36a39c8f95f41552contextConfigLocation02b9ad8b27bc78bd91c18db845cdde4af226acac8cb0e4a9d59fcba58b57a899classpath:root-context.xml22c8aeb51b7638a9da01bd5a66154ac11c0ed9b29d4061c50424e545cf7b2ba51d24e586ca31f4bd05eca427459d98c7f573a9ccb524cb86b6b9919be70810beCharacterEncodingFilterb4d5e6fde2c78ede331e20c60d37da11e5b954f5d6752e2b67f5dbec1cf5c85eorg.springframework.web.filter.CharacterEncodingFilter3c5315e9114c0f42d7a83b06562caa88380fae52cc7d04565d26dd4bbf4b5460c13d9669d2c8f87a36a39c8f95f41552encoding02b9ad8b27bc78bd91c18db845cdde4af226acac8cb0e4a9d59fcba58b57a899UTF-822c8aeb51b7638a9da01bd5a66154ac18f161518881ffd7712eaaadc573a3556380fae52cc7d04565d26dd4bbf4b5460c13d9669d2c8f87a36a39c8f95f41552forceEncoding02b9ad8b27bc78bd91c18db845cdde4af226acac8cb0e4a9d59fcba58b57a899true22c8aeb51b7638a9da01bd5a66154ac18f161518881ffd7712eaaadc573a355694e66dfbd9fa8f117002935bdd35d0b3dd0dfb26ea66647667f179a739921d33f573a9ccb524cb86b6b9919be70810beCharacterEncodingFilterb4d5e6fde2c78ede331e20c60d37da1166e1775cbd9d5002635ae3285442ba88/*3ec4a5583206d351b61ed79c1a0f9c66e354d6d34e50ca0d695db95544b3672a1d24e586ca31f4bd05eca427459d98c7f573a9ccb524cb86b6b9919be70810besitemeshb4d5e6fde2c78ede331e20c60d37da11e5b954f5d6752e2b67f5dbec1cf5c85ecom.opensymphony.sitemesh.webapp.SiteMeshFilter3c5315e9114c0f42d7a83b06562caa8894e66dfbd9fa8f117002935bdd35d0b3dd0dfb26ea66647667f179a739921d33f573a9ccb524cb86b6b9919be70810besitemeshb4d5e6fde2c78ede331e20c60d37da1166e1775cbd9d5002635ae3285442ba88/*3ec4a5583206d351b61ed79c1a0f9c66e354d6d34e50ca0d695db95544b3672a46309ed845064fdb06e746051efff9e0700b5f17c4d842e4bd410f680f40946bappServlet72eca723e64ddd01187c8b4d58572fcbb472d9135dbff3dd7fcc77f5995c97d0org.springframework.web.servlet.DispatcherServlet4f01b97d64aea37f699ead4eb7bd2bbd380fae52cc7d04565d26dd4bbf4b5460c13d9669d2c8f87a36a39c8f95f41552contextConfigLocation02b9ad8b27bc78bd91c18db845cdde4af226acac8cb0e4a9d59fcba58b57a899classpath:servlet-context.xml22c8aeb51b7638a9da01bd5a66154ac18f161518881ffd7712eaaadc573a35564781e2cbaa93c386271b418d3a01af0813065abc64b27fbca30c0905ab93e8ea020d42bb762ac7d7e594da3a264e47fcc870ae7edaa11700bcea972d006efb06e700b5f17c4d842e4bd410f680f40946bappServlet72eca723e64ddd01187c8b4d58572fcb66e1775cbd9d5002635ae3285442ba88/3ec4a5583206d351b61ed79c1a0f9c66cb808b0e21d3ee32c89fe10adc3f12ecf3f5604d5528b766199471609c7e722eeae7f28921fa176b20e23abb843be0905948543310f2c9ae6eabc90d07fdac18org.springframework.web.context.ContextLoaderListenera5cb73ed00d90e1dafbf6168c4a676c2f26bc28f07f75d604e1d9c5e7de10123de02ef028bd8b9a79de42b2beabf35ebeae7f28921fa176b20e23abb843be0905948543310f2c9ae6eabc90d07fdac18com.zealer.ad.listener.ThreadStartUpListensera5cb73ed00d90e1dafbf6168c4a676c2f26bc28f07f75d604e1d9c5e7de10123eae7f28921fa176b20e23abb843be0905948543310f2c9ae6eabc90d07fdac18com.zealer.ad.listener.SessionLifecycleListenera5cb73ed00d90e1dafbf6168c4a676c2f26bc28f07f75d604e1d9c5e7de10123
    f0e92f654589c392f4bce55576ef09df  f1e8976e483ae51232e262b5342c464c   fa71b69717bc99e9a78fbc85d8a96339/tag09895297a0aa8662f06901bffdbb71d1   96344b67689bfb9376de746be45b7a6b/WEB-INF/tag/tag.tldbafd8e2dbced6979955b7cae9142033d  328c2203205d81cf46ea0b2c6a2671eeec05f097bfa9cd9364ff55ce9622d108145f58f625840b9ea02ee646738753d64dc738b987c616c936501769be741a6eindex.jsp61b13b5331cf95fd092fcea0d23c370c300e6fadd23fafd1b065a779b865fda92154b31975826eec7c9ecbf8f296fb33ac238ff21ee5e16243d046a43ee626d2453152a4ea4663b36e0b3abf7880663fbce74d0d5e0feeabcbab17c56a2dfd7fed9ec23d40699efb4cb39a61797a06a5a1

  2、编写一个ThreadStartUpListenser类,实现ServletContextListener,tomcat启动时创建后台线程

  ThreadStartUpListenser.java

package com.zealer.ad.listener;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.stereotype.Component;import com.zealer.ad.task.WatchFilePathTask;

@Componentpublic class ThreadStartUpListenser implements ServletContextListener
{private static WatchFilePathTask r = new WatchFilePathTask();private Log log = LogFactory.getLog(ThreadStartUpListenser.class);    /* * tomcat启动的时候创建一个线程
     * */@Overridepublic void contextInitialized(ServletContextEvent paramServletContextEvent)
    {
        r.start();
        log.info("ImportUserFromFileTask is started!");
    }    /* * tomcat关闭的时候销毁这个线程
     * */@Overridepublic void contextDestroyed(ServletContextEvent paramServletContextEvent)
    {
        r.interrupt();
    }

}

  3、创建指定目录文件变化监控类

    WatchFilePathTask.java

  WatchFilePathTask  Log log = LogFactory.getLog(WatchFilePathTask.   String filePath = ConfigUtils.getInstance().getValue("userfile_path" watchService ="获取监控服务"+="@@@:Path:"+ String todayFormat = DateTime.now().toString("yyyyMMdd"= = existFiles.listFiles( ((todayFormat+".txt"  ( !=ImportUserFromFileTask task = (ImportUserFromFileTask) SpringUtils.getApplicationContext().getBean("importUserFromFileTask"WatchKey key = (= (WatchEvent6b3d0130bba23ae47fe2b8e8cddf0195String fileName =((todayFormat+".txt"= path.toFile().getAbsolutePath()+File.separator+"import filePath:"+ImportUserFromFileTask task = (ImportUserFromFileTask) SpringUtils.getApplicationContext().getBean("importUserFromFileTask");"启动线程导入用户数据"+

  4、创建解析用户文件及导入数据库线程,由WatchFilePathTask启动

package com.zealer.ad.task;import com.zealer.ad.entity.AutoPutUser;import com.zealer.ad.entity.Bmsuser;import com.zealer.ad.service.AutoPutUserService;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.joda.time.DateTime;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStreamReader;import java.util.Date;import javax.annotation.Resource;/**
 * 解析用户文件及入库线程,由WatchFilePathTask启动
 * @author cancer
 * */public class ImportUserFromFileTask extends Thread {private Log log = LogFactory.getLog(ImportUserFromFileTask.class);private String fileName;
    @Resource(name = "autoPutUserService")private AutoPutUserService autoPutUserService;

    @Overridepublic void run() {
        File file = new File(fileName);if (file.exists() && file.isFile()) {
            log.debug(":@@@准备开始休眠10秒钟:" + file);//休眠十分钟,防止文件过大还没完全拷贝到指定目录下,这里的线程就开始读取文件try {
                sleep(10000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }

            InputStreamReader read;try {
                read = new InputStreamReader(new FileInputStream(file), "UTF-8");

                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt = null;int count = 0;
                Boolean f = false;while ((lineTxt = bufferedReader.readLine()) != null) {if ((null == lineTxt) || "".equals(lineTxt)) {continue;
                    }if (lineTxt.startsWith("'")) {
                        lineTxt = lineTxt.substring(1, lineTxt.length());
                    }//解析分隔符为', 'String[] lines = lineTxt.split("', '");int length = lines.length;if (length < 2) {continue;
                    }

                    Bmsuser bmsuser = new Bmsuser();
                    bmsuser.setName(lines[0]);if (!"".equals(lines[1])) {
                        bmsuser.setCity(lines[1]);
                    }
            //根据唯一索引已经存在的数据则不插入f = autoPutUserService.insertIgnore(bmsuser);if (f) {
                        count++;
                    }
                }//汇总数据AutoPutUser autoPutUser = new AutoPutUser();
                autoPutUser.setTotalCount(autoPutUserService.getUserCount());
                autoPutUser.setCount(count);
                autoPutUser.setCountDate(new Date(System.currentTimeMillis()));

                String today = DateTime.now().toString("yyyy-MM-dd");
                Integer oldCount = autoPutUserService.getOldCount(today);//如果今天导入过了就更新否则插入if (!oldCount.equals(0)) {
                    autoPutUserService.updateUserData(autoPutUser, today,
                        oldCount);
                } else {
                    autoPutUserService.gatherUserData(autoPutUser);
                }//注意:要关闭流                read.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

            File newFile = new File(file.getPath() +System.currentTimeMillis() + ".complate");
            file.renameTo(newFile);
        } else {
            log.error(fileName + " file is not exists");
        }
    }public String getFileName() {return fileName;
    }public void setFileName(String fileName) {this.fileName = fileName;
    }public AutoPutUserService getAutoPutUserService() {return autoPutUserService;
    }public void setAutoPutUserService(AutoPutUserService autoPutUserService) {this.autoPutUserService = autoPutUserService;
    }
}

 

附带:

1、sql脚本

CREATE TABLE `bmsuser` (
  `id` int(255) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL ,
  `city` varchar(32) DEFAULT NULL COMMENT ,  PRIMARY KEY (`bmsid`),  UNIQUE KEY `bbLoginName` (`bbLoginName`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

2、文件格式,命名为yyyyMMdd.txt

&#39;张三&#39;, &#39;深圳&#39;

 

以上是java利用WatchService实时监控某个目录下的文件变化并按行解析实例详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?Mar 17, 2025 pm 05:46 PM

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。

如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?Mar 17, 2025 pm 05:44 PM

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?Mar 17, 2025 pm 05:43 PM

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Mar 17, 2025 pm 05:35 PM

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境