Spring Boot集成OpenCSV读取CSV时首列值为null的问题
解决OpenCSV读取CSV首列返回null的问题
核心原因:UTF-8 BOM干扰
绝大多数情况下,首列读取为null是因为CSV文件开头带有UTF-8 BOM(字节顺序标记)。BOM是文件开头的三个隐藏字节(EF BB BF),会被解析为首列列名的前缀,导致实体类中@CsvBindByName(column = "Departure")无法匹配实际读取到的\uFEFFDeparture。
解决方案1:手动跳过BOM
修改文件读取逻辑,检测并跳过BOM:
Path filePath = Paths.get(path); Reader reader; // 检查文件开头是否存在UTF-8 BOM byte[] bom = new byte[3]; try (InputStream is = Files.newInputStream(filePath)) { int read = is.read(bom); boolean hasBom = read == 3 && bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF; if (hasBom) { // 跳过BOM后创建Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8); } else { // 没有BOM,重置流后创建Reader is.reset(); reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8); } } // 后续的CsvToBean逻辑不变 CsvToBean<CsvBikeTrips> csvToBean = new CsvToBeanBuilder(reader) .withType(CsvBikeTrips.class) .withIgnoreLeadingWhiteSpace(false) .build(); List<CsvBikeTrips> csvBikeTrips = csvToBean.parse();
解决方案2:使用BOM处理工具类
如果项目中已引入Apache Commons IO依赖,可直接用BOMInputStream简化代码:
Reader reader = new InputStreamReader( new BOMInputStream(Files.newInputStream(Paths.get(path))), StandardCharsets.UTF_8 ); // 后续解析逻辑不变
验证方法
可以先打印首行的列名,确认是否存在BOM:
BufferedReader br = Files.newBufferedReader(Paths.get(path), StandardCharsets.UTF_8); String header = br.readLine(); String firstColumn = header.split(",")[0]; System.out.println("实际读取的首列名:'" + firstColumn + "'"); System.out.println("首列名长度:" + firstColumn.length()); // 正常Departure长度为8,带BOM则为9
如果输出的首列名长度是9,说明确实存在BOM干扰。
内容的提问来源于stack exchange,提问作者Erkan Isuf
相关产品推荐
相关产品推荐

