2000w的數據在網上搞得沸沸揚揚,做爲技術宅的咱們也來湊湊熱鬧.
據瞭解網上有兩個版一個是數據庫文件另外一個是CSV文件的,前者大小有好幾個G後者才幾百M.對於不是土豪的咱們固然下載幾百M的.至於在哪下載,請各位發揮吊絲精神GOOGLE一下吧,咱們這裏只探討技術,呵呵.
下載後解壓的文件以下:
數據被拆分爲11個CSV文件,這樣咱們能夠寫一個簡單的程序對這些文件進行簡單的搜索,如搜索姓名,手機號或身份證等.通常咱們會採用多線程進行處理,最簡單就是每一個線程處理一個文件,這個相信你們都會...因此咱們這裏不討論多線程,而是多進程.說到多進程處理相對於多線程有什麼好處?如下是本人的一些劣見,有什麼不妥請指正:java
如今咱們將採用多進程對有2000w記錄的文本文件進行簡單的搜索,爲何說是簡單搜索,由於咱們不追求搜索效率,只要達到搜索目的,並不那麼慢就OK了.不知你們對一次關鍵字搜索5分鐘左右能不能接受?不過不接受也沒辦法,咱們這裏不研究算法,只介紹多進程處理.
JVMPart是一個開源的Java多進程處理工具,中文應該叫JVM分拆/割吧,不過我以爲叫"雙P"更合適,由於裏面要實現關鍵的兩個接口——Partitioner和Processor.更多請了解:https://code.google.com/p/jvmpart/
JVMPart使用很是簡單,只要實現Partitioner和Processor兩個接口.Partitioner的做用就是決定數據怎麼分拆,並把分拆出來的參數傳給Processor,Processor就是利用Partitioner傳過來的參數進行具體的處理.就咱們要實現的這個搜索,Partitiner就是讀取CSV目錄裏的文件並把文件路徑和關鍵字傳給Processor,Processor就根據文件路徑讀取文件並利用關鍵字搜索該文件找到了就顯示出來.下面是"雙P"的代碼實現:算法
Partitioner:數據庫
public class Hotel2000WPartitioner extends SimplePartitioner { private String keyword = null; private String dir = null; private String[] filenames = null; public Hotel2000WPartitioner(String dir, String keywords) { this.dir = dir; this.filenames = findFilenames(new File(dir)); this.keyword = keywords; } private static String[] findFilenames(File dir) { String[] filenames = dir.list(new FilenameFilter() { public boolean accept(File dir, String filename) { return filename.toUpperCase().endsWith("CSV"); } }); return filenames; } /** * 決定分爲幾個進程處理 */ @Override public int getTotalProcessor() { return filenames.length; } /** * 把參數傳給Processor */ @Override public Map<String, Object> processorParams(int index) { Map<String, Object> params = new HashMap<String, Object>(); params.put("filename", dir+File.separator+filenames[index]); params.put("keyword", keyword); return params; } }
Processor:多線程
public class Hotel2000WProcessor extends AbsProcessor { /** * 讀取文件並利用關鍵字搜索該文件 */ @Override public void doExecute() throws JvmProcessException { String keyword = getParams().get("keyword"); String filename = getParams().get("filename"); File f = new File(filename); BufferedReader dr = null; try { dr = new BufferedReader(new InputStreamReader( new FileInputStream(f), "UTF-8")); while (dr.readLine() != null) { String line = dr.readLine(); if(line!=null&&line.indexOf(keyword)!=-1) { System.out.println(line); } } } catch (IOException e) { e.printStackTrace(); } finally { if(dr!=null) try { dr.close(); } catch (IOException e) { } } } }
使用JVMPart工具運行:併發
public static void main(String[] args) throws JvmProcessException { String dir = "D:\\個人文檔\\下載\\2000W"; String keyword = "土豪"; JvmProcessPatitionHandler handler = null; // 同時併發三個進程,當其中一個運行完成都踢出另外一個運行 handler = new JvmProcessPatitionHandler(Hotel2000WProcessor.class, 3); Hotel2000WPartitioner partitioner = new Hotel2000WPartitioner(dir, keyword); System.out.println("搜索中,請稍後..."); long time = System.currentTimeMillis(); handler.handle(partitioner); System.out.println("花費時間(分):"+((System.currentTimeMillis()-time)/(1000*60))); }
當程序運行時,咱們能夠經過任務管理器看到有四個java進程在運行(其中一個爲主進程).如圖:jvm
至此, 咱們對2000w數據的搜索已完成,多進程處理就這麼簡單.運行截圖以下(2000w數據果真厲害,土豪也能找到,哈哈):ide
下面附件若是你是WIN32的系統不用安裝JRE,直接運行便可. WIN64沒測試,如不能運行請自行安裝64位JRE再運行.
附件使用方式(前提你已下載了CSV版的數據):
1.解壓後,把程序Hotel2000W拷到CSV文件所在目錄(這一步不作也能夠,程序將提示輸入CSV目錄)
2.雙擊run.bat
3.按提示輸入搜索關鍵字(姓名,手機或身份證等)
4.等待搜索結果,若是找到將在屏幕中出現工具
附件:http://pan.baidu.com/s/19qqvU測試
注:此爲本人在博客園的處女做,但願你們多頂幾下,以示鼓勵!this