java读取带bom的utf-8文件时需跳过bom字节,否则首字符为\ufeff导致解析失败;filereader不支持指定编码且无法识别bom;推荐用fileinputstream检测并跳过bom后构建inputstreamreader,或使用apache commons io的bominputstream自动处理。

Java 读取带 BOM 的 UTF-8 文件时,不能直接用 FileReader 或 InputStreamReader 指定 UTF-8 就完事。因为 BOM(0xEF 0xBB 0xBF)会被当作普通字符读入,变成字符串开头的 \uFEFF,导致首行解析失败、比对异常或显示“”乱码。
为什么 FileReader 不行
FileReader 基于系统默认编码(如 Windows 上是 GBK),不支持显式指定 UTF-8,更不会识别或跳过 BOM。即使你传入 "UTF-8" 参数(某些旧 API 假设支持),它也常被忽略——BOM 字节被错误解码成三个乱码字符,后续内容也全乱。
推荐做法:字节流前置检测 + 跳过
核心逻辑是:先用 FileInputStream 打开文件,读前 3 字节判断是否为 UTF-8 BOM,匹配则跳过,再把处理后的流交给 InputStreamReader。
- 读取前 3 字节,检查是否等于
(byte)0xEF, (byte)0xBB, (byte)0xBF - 若匹配,调用
inputStream.skip(3)或丢弃已读字节 - 用跳过后的流构造
InputStreamReader(inputStream, StandardCharsets.UTF_8) - 后续按正常方式读取(
BufferedReader等),首字符不会再是\uFEFF
更省心的方案:用 Apache Commons IO
手动检测易出错,建议引入 commons-io 库(Maven 坐标:org.apache.commons:commons-io:1.3.2+):
- 使用
BOMInputStream自动探测并跳过 BOM,支持 UTF-8 / UTF-16 / UTF-32 多种类型 - 代码简洁:
new InputStreamReader(new BOMInputStream(fis), StandardCharsets.UTF_8) - 还可调用
bomIn.hasBOM()和bomIn.getBOM()获取检测结果,便于日志或调试
写入带 BOM 的 UTF-8 文件(比如导出 Excel 兼容 CSV)
Windows Excel 依赖 BOM 识别 UTF-8,导出 CSV 时需主动写入:
- 先获取输出流(如
response.getOutputStream()或FileOutputStream) - 手动写入 BOM 字节数组:
out.write(new byte[]{(byte)0xEF, (byte)0xBB, (byte)0xBF}); - 再用
OutputStreamWriter(out, StandardCharsets.UTF_8)写正文内容
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











