Java中使用OpenCSV读取UTF-8 CSV首行首个值附带额外字节问题求解
问题成因
你遇到的问题是UTF-8 BOM(字节顺序标记) 导致的:
- 部分编辑器保存UTF-8编码文件时,会默认在文件开头插入3个不可见的字节
0xEF 0xBB 0xBF(对应Unicode字符\uFEFF),用来标识该文件是UTF-8编码。 - 你当前使用的
FileReader没有处理BOM的逻辑,会将这3个字节解析为普通字符,附加到读取到的第一行第一个字段的开头,导致01实际存储值为\uFEFF01,自然无法匹配查询条件。 - 当你在文件开头新增换行后,BOM会被解析到第一行空记录的内容中,删除第一行后后续内容正常,就是这个原因。
彻底解决方案
有两种常用的无兼容问题的处理方式,不需要修改CSV源文件:
方案1:使用BOM输入流自动过滤BOM(推荐)
借助Apache Commons IO的BOMInputStream自动识别并过滤UTF-8 BOM,同时显式指定文件编码为UTF-8,避免不同系统默认编码不一致导致的乱码问题。
第一步:引入依赖(如果项目未引入)
Maven依赖示例:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency>
第二步:修改createCSVReader方法
修改后的代码如下:
import org.apache.commons.io.input.BOMInputStream; import java.nio.charset.StandardCharsets; static public CSVReader createCSVReader(String CSVPath, String CSVDelimiter) throws IOException { // 用BOMInputStream包裹文件流,自动过滤UTF-8 BOM BOMInputStream bomInputStream = new BOMInputStream(new FileInputStream(CSVPath)); // 显式指定UTF-8编码,避免系统默认编码差异 InputStreamReader reader = new InputStreamReader(bomInputStream, StandardCharsets.UTF_8); return new CSVReaderBuilder(reader) .withCSVParser(createCSVParser(CSVDelimiter)) .build(); }
方案2:手动处理BOM字符(无需额外依赖)
如果不想引入新依赖,可以在读取到内容后手动清除首行首个字段可能存在的BOM字符:
try (CSVReader csvReader = CSVUtils.createCSVReader(masterDataCSVPath, csvDelimiter)) { List<String[]> masterData = csvReader.readAll(); if (!masterData.isEmpty() && masterData.get(0).length > 0) { String firstField = masterData.get(0)[0]; // 判断首字段是否以BOM字符开头,是的话替换掉 if (firstField.startsWith("\uFEFF")) { masterData.get(0)[0] = firstField.replaceFirst("\uFEFF", ""); } } // 后续业务逻辑 }
内容的提问来源于stack exchange,提问作者Balázs Börcsök
相关产品推荐
相关产品推荐

