InputStreamReader是字节流到字符流的桥梁,需显式指定编码(推荐Charset对象),否则易乱码;常用UTF-8、GBK等编码,配合BufferedReader和try-with-resources可高效安全读取文本。

在 Java 中,InputStreamReader 是字节流到字符流的桥梁,它本身不直接读取文件,而是包装一个 InputStream(比如 FileInputStream 或网络输入流),并按指定编码将字节解码为字符。关键在于:**必须显式传入 Charset 或编码名称,否则会使用平台默认编码,极易导致乱码**。
指定编码的两种常用方式
推荐优先使用 Charset 类型参数,类型安全、避免拼写错误;编码名字符串方式更灵活,适合动态配置。
-
用 Charset 对象(推荐):
new InputStreamReader(inputStream, StandardCharsets.UTF_8)
或new InputStreamReader(inputStream, Charset.forName("GBK")) -
用编码名称字符串:
new InputStreamReader(inputStream, "UTF-8")
注意:该构造方法可能抛出UnsupportedEncodingException,需捕获或声明异常
典型使用示例:读取 UTF-8 编码的文本文件
搭配 BufferedReader 提升效率,逐行读取:
try (InputStream is = new FileInputStream("data.txt");
InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
注意:三个资源均实现 AutoCloseable,用 try-with-resources 可自动关闭,避免资源泄漏。
立即学习“Java免费学习笔记(深入)”;
常见编码与注意事项
-
UTF-8:最通用,推荐用于新项目;
StandardCharsets.UTF_8零开销、线程安全 -
GBK / GB2312:中文 Windows 系统旧文件常用;
Charset.forName("GBK")更稳妥(部分 JDK 对 "GB2312" 解析不严格) -
ISO-8859-1:单字节编码,常用于 HTTP header 或兼容场景;
StandardCharsets.ISO_8859_1 - 不要依赖
System.getProperty("file.encoding"),它不可靠,且不能替代显式指定
避免乱码的关键原则
- 读取时用什么编码,写入时就该用什么编码——保持编解码一致
- 从网络(如
HttpURLConnection.getInputStream())读取时,优先从响应头Content-Type中提取 charset,再构建InputStreamReader - 如果不确定源文件编码,可用工具(如
file -i或 IDE 编码探测)先确认,再编码读取


















