InputStreamReader 是将字节流解码为 Unicode 字符流的桥梁类,需显式指定编码(如 UTF-8)以避免乱码,常与 BufferedReader 组合实现高效按行读取。

InputStreamReader 是 Java 中用于将字节流(InputStream)转换为字符流(Reader)的桥梁类,它本身属于字符输入流,但底层依赖字节流,并支持指定字符编码。它的核心作用是**解码**:把原始字节按指定编码(如 UTF-8、GBK)转成 Java 内部使用的 Unicode 字符。
为什么需要 InputStreamReader?
Java 的 I/O 分为两类:
- 字节流(InputStream / OutputStream):直接读写 8 位字节,适合处理图片、音频、网络数据等二进制内容,不关心字符编码。
-
字符流(Reader / Writer):读写 16 位 Unicode 字符,专为文本设计,自动处理编码转换——但不能直接操作字节源(比如
System.in或网络 socket 输入流)。
而像键盘输入(System.in)、网络响应体、文件字节流等,本质都是字节数据。要以“文本方式”安全读取它们,就必须用 InputStreamReader 做一次编码解码转换。
基本用法:绑定字节流 + 指定编码
构造 InputStreamReader 时,至少传入一个 InputStream;推荐同时指定字符集,避免使用平台默认编码(易出乱码):
立即学习“Java免费学习笔记(深入)”;
InputStream in = System.in; // 或 new FileInputStream("a.txt")
InputStreamReader reader = new InputStreamReader(in, "UTF-8"); // 显式指定编码
常见写法组合:
- 从控制台读文本:
new InputStreamReader(System.in, "UTF-8") - 读取 UTF-8 编码的文件:
new InputStreamReader(new FileInputStream("data.txt"), "UTF-8") - 读取 HTTP 响应体(如
HttpURLConnection.getInputStream())时,根据响应头Content-Type中的charset动态指定编码
配合 BufferedReader 提升效率和功能
InputStreamReader 本身只提供逐字符(read())或批量字符(read(char[]))读取能力,不支持按行读取。实际开发中,几乎总是把它包装进 BufferedReader:
InputStream in = System.in; InputStreamReader reader = new InputStreamReader(in, "UTF-8"); BufferedReader br = new BufferedReader(reader); String line = br.readLine(); // ✅ 支持按行读取
也可以链式写成一行:
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in, "UTF-8")
);
这样就能安全、高效地读取用户输入或文本文件,且不会因编码不匹配导致中文乱码。
注意编码一致性与异常处理
关键细节:
- 写入端(如记事本保存文件)用的是什么编码,读取端就该用相同编码创建
InputStreamReader,否则必然乱码。 - 构造时若编码名错误(如写成
"UTF8"而非"UTF-8"),会抛UnsupportedEncodingException,需捕获或声明抛出。 - 建议始终显式指定编码,不要依赖
InputStreamReader(InputStream)无参构造——它用Charset.defaultCharset(),不同环境结果可能不同。
不复杂但容易忽略。


















