Java は WatchService を使用してディレクトリ内のファイルの変更をリアルタイムで監視し、行ごとに解析します。

怪我咯
リリース: 2017-06-25 10:11:28
オリジナル
1712 人が閲覧しました

まず最初に、要件について説明します: 合意された形式でファイルを FTP 経由でサーバー上の指定されたディレクトリにアップロードします。アップロードされたファイル形式が条件を満たしている場合、アプリケーションはディレクトリ内のファイルの変更をリアルタイムで監視できます。要件を満たしている場合、各行を読み取って解析し、それをデータベースに書き込み、解析後にファイルの名前を変更します。

1. 最初のアイデア

指定されたディレクトリ内のファイルの変更を 1 分ごとに読み取るスケジュールされたタスクを設定します。形式に一致するファイルがある場合は、それらを解析します。

この方法は非常に面倒で非効率です。状態のトラバース、保存、比較にすべての効率が消費されます。 また、OS の多くの機能を活用できなくなります。

2. WatchService の概要

1. このクラスのオブジェクトは、オペレーティング システムのネイティブ ファイル システム モニターです。 OS 独自のファイル システム モニターがシステム上のすべてのファイルの変更を監視できることは誰もが知っています。この種の監視では、信号の送受信に基づいた監視が行われるため、効率が最も高くなります。パッケージ化後、Java プログラムで OS ファイル システム モニターを直接使用できます。

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

ii. クラス名 FileSystems から、これが OS プラットフォームのファイル システムに属していることがわかります。

理解する必要はありません。この一連の方法については、ここで詳しく説明します。最初にその使用方法を知っておく必要があります。オペレーティング システムで複数のモニターを同時にオンにできることは誰もが知っています。 Java プログラムでは例外はなく、同じコードを使用して複数のモニターを同時に取得することもできます。

4. モニターは、実際にはファイルの変更によって送信されるシグナルを監視するバックグラウンド スレッドです。ここで上記のコードを通じて取得されたモニターは、単に新しく初期化されたスレッドであり、準備完了状態にもなっていません。

3. 実装プロセス

初期化中にスレッドを作成し、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.作成ディレクトリファイル変更監視クラスを指定します
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 = (= (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.

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 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!