用gbk编码的inputstreamreader读取中文文件需确保编码与文件真实编码一致,通过记事本、notepad++或file/juniversalchardet验证编码,显式指定standardcharsets.gbk构造,再包装bufferedreader高效按行读取,且输入流必须首次直接传入。

直接用 InputStreamReader 指定 GBK 编码读取,就能准确还原中文字符。关键不是“转换”,而是让解码过程与文件真实编码严格一致。
确认文件确实是 GBK 编码
乱码的第一步往往是猜错编码。不能凭感觉写 "GBK",得有依据:
- 用记事本打开文件 → “另存为”看默认编码(Windows 系统下旧版记事本保存的文本大概率是 GBK)
- 用 Notepad++ 打开 → 查看右下角状态栏显示的编码(如 “ANSI” 在中文 Windows 下通常对应 GBK)
- 命令行工具验证:
file -i filename.txt(Linux/macOS)或用 Java 工具库(如 juniversalchardet)做编码探测
用 GBK 构造 InputStreamReader
必须显式传入 Charset,绝不能依赖无参构造器:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- ✅ 正确写法(推荐 Java 7+):
new InputStreamReader(new FileInputStream("data.txt"), StandardCharsets.GBK) - ✅ 兼容写法(字符串名,大小写不敏感):
new InputStreamReader(new FileInputStream("data.txt"), "GBK") - ❌ 错误写法:
new InputStreamReader(new FileInputStream("data.txt"))—— 它用系统默认编码(Linux 是 UTF-8,Windows 是 GBK),跨平台必出问题
搭配 BufferedReader 高效读取
InputStreamReader 本身只支持单字符读取,实际使用应包装成 BufferedReader:
- 提升性能:带缓冲,避免频繁系统调用
- 支持按行读:
readLine()直接返回完整字符串,中文不会被截断 - 典型组合:
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.GBK))
注意输入流不能被提前读取
InputStreamReader 是装饰器,它从字节流开头开始解码:
- 如果在创建它之前调用了
is.read()或is.mark(),流指针已移动,后续解码会丢失开头、错位,甚至抛MalformedInputException - 确保
FileInputStream或其他原始流,**直接、首次**交给InputStreamReader - 调试时可打印前几个字节(
is.read(new byte[4]))验证是否从头开始,但生产代码中不要这么做
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










