inputstreamreader 是字节流到字符流的桥梁,需显式指定字符编码(如 "utf-8")以避免乱码,推荐使用带 charsetname 参数的构造方法,并常与 bufferedreader 组合提升读取效率。

在 Java 中,InputStreamReader 是字节流到字符流的桥梁,核心作用是将原始字节流(如 FileInputStream 或网络输入流)按指定字符编码解码为字符流,从而解决乱码问题。关键在于显式指定编码名,否则会依赖平台默认编码,极易出错。
明确指定编码,避免使用默认构造函数
InputStreamReader 有两个常用构造方法:
-
new InputStreamReader(InputStream in)—— 使用系统默认编码(如 Windows 是 GBK,Linux/macOS 通常是 UTF-8),不可靠,不推荐 -
new InputStreamReader(InputStream in, String charsetName)—— 显式传入编码名(如"UTF-8"、"GBK"),安全可控
例如读取一个 UTF-8 编码的文本文件:
FileInputStream fis = new FileInputStream("data.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); // ✅ 指定编码
配合 BufferedReader 提升读取效率和便利性
InputStreamReader 本身只做解码,不带缓冲;逐字符读取效率低。通常包装成 BufferedReader,支持按行读取:
try (FileInputStream fis = new FileInputStream("notes.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
注意:资源自动关闭顺序按声明从左到右,确保 InputStream 最后被关闭。
处理编码未知或可能出错的情况
如果文件编码不确定(如用户上传的文本),可先尝试常见编码,捕获 UnsupportedEncodingException 或读取时出现乱码(如显示“”),再 fallback:
- 优先尝试
"UTF-8"(含 BOM 的 UTF-8 会被自动识别) - 再试
"GBK"(中文 Windows 常见) - 必要时用工具类检测编码(如 ICU4J 或 juniversalchardet)
简单 fallback 示例:
String[] encodings = {"UTF-8", "GBK", "ISO-8859-1"};
for (String enc : encodings) {
try (InputStreamReader isr = new InputStreamReader(
new FileInputStream("input.txt"), enc)) {
if (isReadable(isr)) { // 自定义校验逻辑,比如检查是否含大量
// 使用该编码继续处理
break;
}
} catch (UnsupportedEncodingException | IOException ignored) {}
}
写入时也需注意编码一致性
虽然 InputStreamReader 用于输入,但编码问题常伴随输出。若用 OutputStreamWriter 写入,同样必须显式指定编码,并与读取端一致:
try (FileOutputStream fos = new FileOutputStream("output.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw)) {
bw.write("你好,世界!");
}
否则读写编码不匹配,必然导致乱码。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











