OpenCSV正確處理反斜線

OpenCSV正確處理反斜線

  • 2018.3.13
  • 版權聲明:本文爲博主chszs的原創文章,未經博主允許不得轉載。

OpenCSV是一個開源的、處理CSV數據的Java庫。但它在處理反斜槓時存在一個小問題,本文講述這個問題以及如何解決它。

OpenCSV的Maven依賴如下:

    <dependency>
        <groupId>com.opencsv</groupId>
        <artifactId>opencsv</artifactId>
        <version>4.1</version>
    </dependency>

問題

下面是使用OpenCSV編寫的讀取CSV數據的一個代碼片段:

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
......
String dataValue = "test";
// writing  
StringWriter writer = new StringWriter();
try (CSVWriter csvwriter = new CSVWriter(writer)) {
    String[] originalData = new String[2];
    originalData[0] = dataValue;
    originalData[1] = dataValue;
    System.out.println("Original data: " + originalData[0] + "," + originalData[1]);
    csvwriter.writeNext(originalData);
} catch (IOException e) {
    throw new RuntimeException(e);
}
System.out.println("Written data: " + writer.toString());
// reading
try (CSVReader csvReader = new CSVReader(new StringReader(writer.toString()))) {
    String[] readData = csvReader.readNext();
    System.out.println("Read data: " + readData[0] + "," + readData[1]);
} catch (IOException e) {
    throw new RuntimeException(e);
}

上面的代碼片段輸出如下:

Original data: test,test
Written data: "test","test"

Read data: test,test

這是預期的結果。但是,如果在CSV數據中遇到反斜線字符(’\’),OpenCSV就會遇到問題。

假定dataValue帶有反斜線字符:

String dataValue = "t\\est";

輸出如下:

Original data: t\est,t\est
Written data: "t\est","t\est"

Read data: test,test

請注意,讀取CSV數據中的反斜線字符消失了。

原因

默認情況下,CSVReader使用雙反斜線(’\’)作爲其轉義字符。同時,CSVWriter使用雙引號(’“’)作爲轉義字符。

因此,反斜線字符會導致不正確的轉義。在讀數據時,CSVParser將忽略單個反斜線字符,因爲它是轉義字符。

解決方案

默認情況下,CSVReader使用CSVParser解析CSV數據。OpenCSV還提供了一個嚴格遵循RFC4180標準的解析器:RFC4180Parser。

使用RFC4180Parser解析器,CSVReader會以雙引號(’“’)作爲轉義字符,這樣就可以與CSVWriter的轉義方式保持一致。

故上面的代碼片段可以修改如下:

// reading
RFC4180Parser rfc4180Parser = new RFC4180ParserBuilder().build();
CSVReaderBuilder csvReaderBuilder = new CSVReaderBuilder(new StringReader(writer.toString())).withCSVParser(rfc4180Parser);
try (CSVReader csvReader = csvReaderBuilder.build()) {
    String[] readData = csvReader.readNext();
    System.out.println("Read data: " + readData[0] + "," + readData[1]);
} catch (IOException e) {
    throw new RuntimeException(e);
}

執行代碼,輸出:

Original data: t\est,t\est
Written data: "t\est","t\est"

Read data: t\est,t\est

補充一句,也可以選擇Apache Commons CSV開源庫,它也是很好的選擇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章