用inputstreamreader搭配fileinputstream可可靠读取跨平台文本文件,关键在于显式指定字符编码(如utf-8)、用bufferedreader处理换行符差异、try-with-resources自动关闭资源,并注意bom处理。

用转换流(InputStreamReader)搭配文件字节流(FileInputStream),能可靠读取不同平台生成的文本文件,关键是正确处理字符编码和换行符差异。
用 InputStreamReader 统一解码字节流
文件本质是字节,不同系统保存文本时可能用 UTF-8、GBK 或 ISO-8859-1 等编码。直接用 FileInputStream 读会得到原始字节,无法正确转成字符串。转换流的作用就是把字节按指定编码“翻译”成字符:
- 显式指定编码(推荐):如
new InputStreamReader(new FileInputStream("a.txt"), StandardCharsets.UTF_8) - 不指定编码则依赖平台默认(Windows 常为 GBK,Linux/macOS 常为 UTF-8),易出乱码,应避免
- 若不确定源文件编码,可先用工具(如
file -i或 IDE 编码探测)判断,或用UniversalDetector类尝试识别
用 BufferedReader 安全读取并兼容换行符
不同系统换行符不同:Windows 用 \r\n,Linux/macOS 用 \n,老 Mac 用 \r。单独用 InputStreamReader 逐字符读需手动处理这些差异。套一层 BufferedReader 可以屏蔽底层差异:
-
readLine()方法自动识别并截掉任意一种换行符,返回纯文本行 - 它内部已做缓冲,比逐字节/字符读更高效
- 示例组合:
new BufferedReader(new InputStreamReader(new FileInputStream("log.txt"), StandardCharsets.UTF_8))
使用 try-with-resources 自动释放资源
文件流和转换流都实现 AutoCloseable,跨平台代码必须确保及时关闭,否则在某些系统(尤其 Windows)上可能锁住文件:
- 嵌套声明即可:
try (FileInputStream fis = new FileInputStream("data.txt");<br> InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);<br> BufferedReader br = new BufferedReader(isr)) {<br> // 读取逻辑<br>} // 自动按 br → isr → fis 顺序关闭 - 避免只关外层(如只关
BufferedReader)而漏掉底层流,虽然多数 JDK 版本中BufferedReader.close()会级联关闭,但显式声明更清晰可靠
补充:处理 BOM(字节顺序标记)
UTF-8 文件有时开头带 BOM(EF BB BF),虽非必需,但部分编辑器(如 Windows 记事本)会写入。Java 的 InputStreamReader 默认不跳过它,可能导致首行出现异常字符(如 Hello 中的隐藏符号):
- 可手动检测并跳过:读前用
FileInputStream检查头三个字节是否为 BOM,是则skip(3) - 更稳妥方式:改用
Files.newBufferedReader(Paths.get("f.txt"), StandardCharsets.UTF_8),JDK 7+ 的该方法会自动忽略 UTF-8 BOM - 若需兼容多种编码且含 BOM,可用第三方库如 Apache Commons IO 的
BOMInputStream










