我有一个代码,读取CSV文件并使用CsvToBean
将内容转换为Java对象。
public static <T> List<T> parseInputStreamFromCsv(InputStream inputStream, Class<T> clazz) {
try (Reader reader = new BufferedReader(new InputStreamReader(inputStream))) {
CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(reader)
.withType(clazz)
.withIgnoreLeadingWhiteSpace(true)
.build();
return csvToBean.parse();
} catch (Exception ex) {
throw new ConversionFailedException("Error converting CSV");
}
}
有时用户上传CSV文件时使用逗号作为分隔符,然后其他用户上传CSV文件时使用分号作为分隔符。
我的问题是存在一种在我的CsvToBeanBuilder
中动态设置分隔符的方法,创建一种转换两个文件(使用逗号和分号)的方法,而不会出现任何问题。谢谢!
我的问题是存在一种在我的CsvToBeanBuilder
中动态设置分隔符的方法,创建一种转换两个文件(使用逗号和分号)的方法,而没有任何问题。
以下方法将同时处理分隔符;
和,
:
使用动态分隔符检测解析
注意:
根据OP的要求,下面的方法支持两个主要字符分隔行条目
public static <T> List<T> parseFromCsvWithSeparatorDetection(
InputStream inputStream, Class<T> type, String[] columns)
throws IOException, CsvException {
final StringBuilder textBuilder = new StringBuilder();
try (Reader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
int c;
while ((c = reader.read()) != -1) {
textBuilder.append((char) c);
}
}
final String csvContent = textBuilder.toString();
final char detectedSeparator;
if(csvContent.contains(";")) {
detectedSeparator = ';'; // semicolon case
} else {
detectedSeparator = ','; // default case
}
try (Reader reader = new StringReader(csvContent)) {
ColumnPositionMappingStrategy<T> strategy = new ColumnPositionMappingStrategy<>();
strategy.setColumnMapping(columns);
strategy.setType(type);
CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(reader)
.withMappingStrategy(strategy)
.withSeparator(detectedSeparator)
.withIgnoreLeadingWhiteSpace(true)
.build();
return csvToBean.parse();
}
}
用法示例String[] columns = new String[]{"a", "b"};
InputStream in = ... // <-- set/obtain InputStream here
try {
List<Bean> objects = CSVUtils.parseFromCsvWithSeparatorDetection(in, Bean.class, columns);
} catch (IOException | CsvException e) {
e.printStackTrace();
}
给定类Bean
有两个String属性a
和b
,一个无参数的构造函数(和getter/setter方法)
演示csv数据
A1;B1
A2;B2
和
A1,B1
A2,B2
我用17和OpenCSV 5.7.1测试了上面的内容,也应该适用于更老的或最近的5。x版本。
洞穴!
上面的方法应该只能如果用于处理的内存在运行时不是问题,则使用。原因:inputStream
被完全消耗并读取到内存中——然而,只有一次。然而,在低资源环境下或使用非常大的(而且很可能是巨大的)csv文件(可能有数百万行)时,这可能会有问题。