java读取utf-8带bom文件时需手动跳过ef bb bf三字节bom,否则首字符为\ufeff导致解析异常;应使用fileinputstream配合inputstreamreader指定utf-8编码,或封装bomskippinginputstream,禁用filereader。

Java 字符流读取 UTF-8 带 BOM 文件时,BOM(EF BB BF)会被当作普通字符读入,导致首字段多出一个不可见的 \uFEFF(零宽无间断空格),引发解析失败或字符串比对异常。核心思路是:在构造字符流前,先用字节流检测并跳过 BOM。
识别并跳过 UTF-8 BOM 的字节序列
UTF-8 的 BOM 是固定的 3 字节:0xEF 0xBB 0xBF。不能依赖 InputStreamReader 自动处理——它不识别 BOM,也不会跳过。必须在包装为字符流前,由 InputStream 手动检查并消费这 3 个字节。
- 用
FileInputStream打开文件,读取前 3 字节 - 若匹配
0xEF, 0xBB, 0xBF,则调用skip(3)或直接丢弃已读字节 - 再将处理后的输入流传给
InputStreamReader,指定"UTF-8"
封装成可复用的 BOM 跳过输入流
避免每次手动判断,推荐封装一个带 BOM 检测的 InputStream 子类或工具方法。例如:
创建 BomSkippingInputStream extends FilterInputStream,在构造时自动探测并跳过 UTF-8 BOM;或者使用 Apache Commons IO 的 org.apache.commons.io.input.BOMInputStream,它支持多种编码 BOM,并提供 hasBOM() 和 getBOM() 方法。
使用示例:
BOMInputStream bomIn = new BOMInputStream(new FileInputStream("file.txt"));<br>
InputStreamReader reader = new InputStreamReader(bomIn, StandardCharsets.UTF_8);
注意 FileReader 的局限性
FileReader 是基于平台默认编码的便捷类,不支持显式指定 UTF-8,更不处理 BOM。即使系统默认编码是 UTF-8,它仍会把 BOM 当作有效字符读入。务必改用 FileInputStream + InputStreamReader 组合,并显式指定 StandardCharsets.UTF_8。
验证是否成功剔除 BOM
读取第一行后,可用 String.trim().isEmpty() 初步判断——若开头有 BOM,trim() 不会去掉 \uFEFF;更可靠的是检查首字符:if (line.length() > 0 && line.charAt(0) == '\uFEFF') { line = line.substring(1); }
但该方式属事后补救,优先推荐前置跳过,避免污染后续逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











