版权声明:本文为博主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开源库,它也是很好的选择。