まず最初に、要件について説明します: 合意された形式でファイルを FTP 経由でサーバー上の指定されたディレクトリにアップロードします。アップロードされたファイル形式が条件を満たしている場合、アプリケーションはディレクトリ内のファイルの変更をリアルタイムで監視できます。要件を満たしている場合、各行を読み取って解析し、それをデータベースに書き込み、解析後にファイルの名前を変更します。
指定されたディレクトリ内のファイルの変更を 1 分ごとに読み取るスケジュールされたタスクを設定します。形式に一致するファイルがある場合は、それらを解析します。
この方法は非常に面倒で非効率です。状態のトラバース、保存、比較にすべての効率が消費されます。 また、OS の多くの機能を活用できなくなります。
1. このクラスのオブジェクトは、オペレーティング システムのネイティブ ファイル システム モニターです。 OS 独自のファイル システム モニターがシステム上のすべてのファイルの変更を監視できることは誰もが知っています。この種の監視では、信号の送受信に基づいた監視が行われるため、効率が最も高くなります。パッケージ化後、Java プログラムで OS ファイル システム モニターを直接使用できます。
i. WatchService watcher = FileSystems.getDefault().newWatchService() ;
ii. クラス名 FileSystems から、これが OS プラットフォームのファイル システムに属していることがわかります。
理解する必要はありません。この一連の方法については、ここで詳しく説明します。最初にその使用方法を知っておく必要があります。オペレーティング システムで複数のモニターを同時にオンにできることは誰もが知っています。 Java プログラムでは例外はなく、同じコードを使用して複数のモニターを同時に取得することもできます。
4. モニターは、実際にはファイルの変更によって送信されるシグナルを監視するバックグラウンド スレッドです。ここで上記のコードを通じて取得されたモニターは、単に新しく初期化されたスレッドであり、準備完了状態にもなっていません。
3. 実装プロセス
初期化中にスレッドを作成し、watchService を使用してディレクトリ内のファイルの変更をリアルタイムで監視し、条件を満たすファイルがあれば追加され、合意された形式に従ってファイルを解析してデータベースに書き込みます。詳しい手順は以下の通りです!
<?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>
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(); } }
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; } }
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;
'张三', '深圳'
以上がJava は WatchService を使用してディレクトリ内のファイルの変更をリアルタイムで監視し、行ごとに解析します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。