如何为OpenCSV的CsvToBean动态设置分隔符兼容两类CSV文件
动态设置CSV分隔符实现兼容解析
当然可以实现,给你两种实用的解决思路:
1. 让调用者指定分隔符(简单直接)
直接修改原方法,新增一个分隔符参数,在构建CsvToBean时通过withSeparator()方法动态设置即可。这种方式逻辑清晰,适合提前知道分隔符的场景。
修改后的代码:
public static <T> List<T> parseInputStreamFromCsv(InputStream inputStream, Class<T> clazz, char separator) { try (Reader reader = new BufferedReader(new InputStreamReader(inputStream))) { CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(reader) .withType(clazz) .withIgnoreLeadingWhiteSpace(true) .withSeparator(separator) // 动态设置分隔符 .build(); return csvToBean.parse(); } catch (Exception ex) { throw new ConversionFailedException("Error converting CSV"); } }
调用时根据文件类型传对应分隔符:
// 解析逗号分隔的CSV List<YourBean> commaList = parseInputStreamFromCsv(inputStream, YourBean.class, ','); // 解析分号分隔的CSV List<YourBean> semicolonList = parseInputStreamFromCsv(inputStream, YourBean.class, ';');
2. 自动检测文件分隔符(更友好)
如果不想让调用者手动指定,可以读取CSV的第一行,统计逗号和分号的数量,用出现次数更多的作为分隔符。这种方式能自动适配两种格式,用户体验更好。
实现代码示例:
public static <T> List<T> parseInputStreamFromCsv(InputStream inputStream, Class<T> clazz) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { // 读取第一行判断分隔符 String firstLine = reader.readLine(); if (firstLine == null) { throw new IllegalArgumentException("Empty CSV file"); } int commaCount = (int) firstLine.chars().filter(c -> c == ',').count(); int semicolonCount = (int) firstLine.chars().filter(c -> c == ';').count(); char separator = commaCount >= semicolonCount ? ',' : ';'; // 重置流到开头(需确保输入流支持标记,若不支持可先将流内容读到内存) inputStream.reset(); try (Reader resetReader = new BufferedReader(new InputStreamReader(inputStream))) { CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(resetReader) .withType(clazz) .withIgnoreLeadingWhiteSpace(true) .withSeparator(separator) .build(); return csvToBean.parse(); } } catch (Exception ex) { throw new ConversionFailedException("Error converting CSV"); } }
内容的提问来源于stack exchange,提问作者João Pedro Peres
相关产品推荐
相关产品推荐

