如何用OpenCSV的CsvToBeanBuilder处理格式错误的行
解决OpenCSV读取CSV时格式错误行的异常捕获与记录问题
方法一:关闭自动抛出异常,批量处理捕获的异常
修改CsvToBeanBuilder配置,添加.withThrowExceptions(false)后,OpenCSV会将解析异常暂存而非直接抛出,避免程序因单一行错误中断。遍历完成后可统一获取并记录所有异常:
// 构建CsvToBean时关闭自动抛出异常 CsvToBean<Bean> cb = new CsvToBeanBuilder(reader) .withType(Bean.class) .withSeparator(',') .withSkipLines(1) .withThrowExceptions(false) // 核心配置:禁用自动抛出异常 .build(); Iterator<Bean> it = cb.iterator(); while (it.hasNext()) { Bean b = it.next(); // 正常处理解析后的Bean对象 } // 遍历结束后批量获取并记录异常 List<CsvException> exceptions = cb.getCapturedExceptions(); for (CsvException e : exceptions) { // 记录关键信息:行号、错误原因、原始行内容 System.out.printf("第%d行解析失败:%s,原始内容:%s%n", e.getLineNumber(), e.getMessage(), e.getLine()); // 可替换为日志框架的记录逻辑,如log.error(...) }
方法二:自定义ExceptionHandler实时处理异常
如果需要在遇到错误行时立即记录,而非等全部遍历完成,可自定义异常处理器并配置到构建器中:
// 自定义实时异常处理器 ExceptionHandler exceptionHandler = new ExceptionHandler() { @Override public void handleException(CsvException e) throws CsvException { // 实时输出异常信息 System.out.printf("实时捕获错误:第%d行解析失败,原因:%s,内容:%s%n", e.getLineNumber(), e.getMessage(), e.getLine()); // 若需终止解析,可重新抛出异常;否则不抛出,继续处理后续行 // throw e; } }; // 构建CsvToBean时配置自定义处理器 CsvToBean<Bean> cb = new CsvToBeanBuilder(reader) .withType(Bean.class) .withSeparator(',') .withSkipLines(1) .withExceptionHandler(exceptionHandler) // 绑定自定义处理器 .build(); Iterator<Bean> it = cb.iterator(); while (it.hasNext()) { try { Bean b = it.next(); // 正常处理Bean对象 } catch (CsvException e) { // 若处理器中重新抛出异常,可在此二次捕获处理 System.out.printf("二次捕获:第%d行解析失败%n", e.getLineNumber()); } }
关键说明
CsvException包含解析错误的核心信息:getLineNumber()获取错误行号(含已跳过的行)、getLine()获取原始行内容、getMessage()获取具体错误原因。- 两种方法可根据业务需求选择:批量处理适合后续统一分析错误,实时处理适合需要即时告警的场景。
内容的提问来源于stack exchange,提问作者semantic-dev
相关产品推荐
相关产品推荐

