標籤:
uniVocity-parsers 是一個開源的Java項目。 針對CSV/TSV/固定寬度文字檔的解析,它以簡潔的API開發介面提供了豐富而強大的功能。後面會做進一步介紹。
和其他解析庫有所不同,uniVocity-parsers以高效能、可擴充為出發點,設計了一套自有架構。基於這套架構,開發人員可以構建出新的檔案解析器。
1. 概述
作為一名Java開發人員,我目前正在參與開發一個Web項目,該項目協助通訊電訊廠商評估當前的網路,並給出解決方案。 在該項目中,CSV檔案扮演著至關重要的角色,它是電訊廠商網路資料的承載格式,這些資料包含寬頻使用者的即時線上狀態(線上/離線),及其即時資料流量。 通常來講,單個CSV檔案可以達到1GB以上,包含上百萬條記錄。項目當前採用的CSV解析庫為JavaCSV。
隨著電訊廠商網路規模的擴張,以及系統監控周期的增加,CSV檔案迅速變大。 項目組不得不解決超大CSV資料解析所帶來的效能問題(甚至包括秒級的解析效率),以及業務變化帶來的功能擴充受到限制的問題。
經過很多次的測試和分析,我們最終確定採用uniVocity-parsers作為CSV檔案解析庫, 實踐之後發現它確實解決了我們的問題。除了更好的效能和擴充性之外,該庫還為開發人員提供了簡潔易懂的API、開發文檔和教程。 對於進階的功能擴充訴求,官方提供對應的收費服務。
該項目託管在Github上,截至目前,已有69個star和10個fork。你可以在這裡和這裡找到相關開發文檔和教程,也可以在這裡找到更多例子和新聞。
值得關注的是,Apache社區知名的開源項目Apache Camel也整合了uniVocity-parsers ,作為該項目解析CSV/TSV/固定寬度文字檔的推薦庫。 更多資訊請查看這裡。
2. 安裝
我們項目組目前在用1.5.1版本, 推薦移步到uniVocity-parsers官方網站下載最新版本。
該項目同時也發發布在了Maven的中心倉庫,因此也可以在你的pom.xml中直接添加如下代碼:
<dependency><groupId>com.univocity</groupId><artifactId>univocity-parsers</artifactId><version>1.5.1</version></dependency>
3. 特性簡介
uniVocity-parsers提供了一系列強大的功能,能夠很好的滿足你所有關於列表式資料的處理需求。如表展現了部分關鍵功能:
4. 讀取列表式資料
讀取CSV中的所有行
CsvParser parser = new CsvParser(new CsvParserSettings());List<String[]> allRows = parser.parseAll(getReader("/examples/example.csv"));
如需查看檔案寫入相關的所有功能,請移步:https://github.com/uniVocity/univocity-parsers#reading-csv
5. 寫入列表式資料
僅需2行代碼,就可以完成CSV格式資料的寫入:
List<String[]> rows = someMethodToCreateRows();CsvWriter writer = new CsvWriter(outputWriter, new CsvWriterSettings());writer.writeRowsAndClose(rows);
如需查看檔案寫入相關的所有功能,請移步: https://github.com/uniVocity/univocity-parsers/blob/master/README.md#writing
6. 效能與擴充性
如下為我們對比 uniVocity-parsers 和 JavaCSV 的測試對比表:
| 檔案大小 |
JavaCSV解析耗時 |
uniVocity-parsers解析耗時 |
| 10MB, 145453 行 |
1138ms |
836ms |
| 100MB, 809008 行 |
23s |
6s |
| 434MB, 4499959 行 |
91s |
28s |
| 1GB, 23803502 行 |
245s |
70s |
在這裡可以查看幾乎所有CSV解析庫的效能對比分析表,從表中可以發現,uniVocity-parsers以絕對優勢領先其他庫。
uniVocity-parsers在效能和靈活性方面的優勢得益於如下設計和機制:
- 以單獨線程讀取資料(通過調用CsvParserSettings.setReadInputOnSeparateThread() 進行設定)
- 並行的行資料處理器 (參考 RowProcessor 的實作類別 ConcurrentRowProcessor)
- 通過繼承 ColumnProcessor 類來根據業務需求處理列資料
- 通過繼承 RowProcessor 類來根據業務需求處理行資料
7. 設計與實現
在uniVocity-parsers中,有一些核心的資料處理模組,他們負責對資料按行讀寫、按列讀寫,以及行列資料的轉換。如下是這些核心模組的關係圖:
你可以通過實現 RowProcessor 介面或者繼承其實作類別來開發自己的資料處理模組。如下代碼中,我通過簡單的內部匿名類開發了自己的資料處理模組。
CsvParserSettings settings = new CsvParserSettings();settings.setRowProcessor(new RowProcessor() {StringBuilder stringBuilder = new StringBuilder();/*** 處理第一行資料之前,你可以根據商務邏輯做相關初始化配置。**/@Overridepublic void processStarted(ParsingContext context) {System.out.println("Started to process rows of data.");}/*** 根據你的商務邏輯,處理行資料**/@Overridepublic void rowProcessed(String[] row, ParsingContext context) {System.out.println("The row in line #" + context.currentLine() + ": ");for (String col : row) {stringBuilder.append(col).append("\t");}}/*** 所有行資料處理完成之後,做清理工作。**/@Overridepublic void processEnded(ParsingContext context) {System.out.println("Finished processing rows of data.");System.out.println(stringBuilder);}});CsvParser parser = new CsvParser(settings);List<String[]> allRows = parser.parseAll(new FileReader("/myFile.csv"));
uniVocity-parsers庫提供的特性不止這些,由於它在我們的項目中發揮了很大的作用,推薦你進一步瞭解。
uniVocity-parsers:一款強大的CSV/TSV/固定寬度文字檔解析庫(Java)