版權聲明:本文為部落客chszs的原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/chszs/article/details/79546866
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開源庫,它也是很好的選擇。