首頁 > Java > java教程 > 主體

java利用WatchService即時監控某目錄下的檔案變化並按行解析實例詳解

怪我咯
發布: 2017-06-25 10:11:28
原創
1712 人瀏覽過

首先說下需求:透過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監聽器設定檔監控監聽器

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    "><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:root-context.xml</param-value></context-param><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter><filter-name>sitemesh</filter-name><filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class></filter><filter-mapping><filter-name>sitemesh</filter-name><url-pattern>/*</url-pattern></filter-mapping><servlet><servlet-name>appServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:servlet-context.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>appServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 配置spring监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 配置监控文件变化监听器 --><listener><listener-class>com.zealer.ad.listener.ThreadStartUpListenser</listener-class></listener><listener><listener-class>com.zealer.ad.listener.SessionLifecycleListener</listener-class></listener>
    <jsp-config>  <taglib>   <taglib-uri>/tag</taglib-uri>   <taglib-location>/WEB-INF/tag/tag.tld</taglib-location>  </taglib></jsp-config><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><session-config><session-timeout>45</session-timeout></session-config></web-app>
登入後複製

  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、建立指定目錄檔案變更監控類別

    #java#PathTask.

#>.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 = (= (WatchEvent<?>String 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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!