天天看點

java 讀取tsv_uniVocity-parsers:一款強大的CSV/TSV/定寬文本檔案解析庫(Java)

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. 安裝

該項目同時也發釋出在了Maven的中心倉庫,是以也可以在你的pom.xml中直接添加如下代碼:

com.univocity

univocity-parsers

1.5.1

3. 特性簡介

uniVocity-parsers提供了一系列強大的功能,能夠很好的滿足你所有關于清單式資料的處理需求。如下圖表展現了部分關鍵功能:

java 讀取tsv_uniVocity-parsers:一款強大的CSV/TSV/定寬文本檔案解析庫(Java)

4. 讀取清單式資料

讀取CSV中的所有行

CsvParser parser = new CsvParser(newCsvParserSettings());

List allRows = parser.parseAll(getReader("/examples/example.csv"));

5. 寫入清單式資料

僅需2行代碼,就可以完成CSV格式資料的寫入:

List rows =someMethodToCreateRows();

CsvWriter writer= new CsvWriter(outputWriter, newCsvWriterSettings());

writer.writeRowsAndClose(rows);

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中,有一些核心的資料處理子產品,他們負責對資料按行讀寫、按列讀寫,以及行列資料的轉換。如下是這些核心子產品的關系圖:

java 讀取tsv_uniVocity-parsers:一款強大的CSV/TSV/定寬文本檔案解析庫(Java)

你可以通過實作 RowProcessor 接口或者繼承其實作類來開發自己的資料處理子產品。如下代碼中,我通過簡單的内部匿名類開發了自己的資料處理子產品。

CsvParserSettings settings = newCsvParserSettings();

settings.setRowProcessor(newRowProcessor() {

StringBuilder stringBuilder= newStringBuilder();@Overridepublic voidprocessStarted(ParsingContext context) {

System.out.println("Started to process rows of data.");

}@Overridepublic voidrowProcessed(String[] row, ParsingContext context) {

System.out.println("The row in line #" + context.currentLine() + ": ");for(String col : row) {

stringBuilder.append(col).append("\t");

}

}@Overridepublic voidprocessEnded(ParsingContext context) {

System.out.println("Finished processing rows of data.");

System.out.println(stringBuilder);

}

});

CsvParser parser= newCsvParser(settings);

List allRows = parser.parseAll(new FileReader("/myFile.csv"));

uniVocity-parsers庫提供的特性不止這些,由于它在我們的項目中發揮了很大的作用,推薦你進一步了解。