Java流装饰器遵循责任链原则,只需关闭最外层流即可自动触发底层流关闭;try-with-resources按声明逆序自动关闭所有资源,确保每个资源仅关闭一次,避免重复关闭或资源泄漏。

嵌套关闭流的关键不是“先关哪个后关哪个”,而是避免重复关闭、防止资源泄漏,同时确保最外层装饰器能触发底层流的关闭。Java 的流装饰器(如 BufferedInputStream、InputStreamReader)在 close() 时会自动调用被包装流的 close(),所以只需关闭最外层流即可。
只关闭最外层流,底层流会自动释放
流的装饰器设计遵循“责任链”原则:调用最外层流的 close(),它会层层向下传递关闭动作。例如:
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"), StandardCharsets.UTF_8));- 只需调用
br.close(),它会依次触发InputStreamReader.close()→FileInputStream.close() - 如果再手动调用
fis.close(),会导致IOException: Stream closed
用 try-with-resources 自动管理嵌套流
这是最安全、最推荐的方式。JVM 会按声明逆序自动关闭所有资源,且每个资源只关一次:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 资源按分号分隔,声明顺序即创建顺序;关闭时从右到左(即最外层先关)
- 即使中间某步抛异常,已成功创建的资源仍会被关闭
- 示例:
try (FileInputStream fis = new FileInputStream("src.txt"); InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8); BufferedReader br = new BufferedReader(isr)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } // 此处 br → isr → fis 依次自动关闭
手动关闭时别漏掉或重复关
若不用 try-with-resources(如旧版 JDK 或特殊逻辑),必须严格按“从外向内”只关一次:
立即学习“Java免费学习笔记(深入)”;
- ✅ 正确:
br.close();(仅此一句) - ❌ 错误:
br.close(); isr.close(); fis.close();(重复关闭引发异常) - ❌ 危险:
fis.close(); br.close();(底层已关,外层再关会报错) - ⚠️ 注意:
flush()不是close(),写入字符流时建议在close()前显式flush(),但BufferedWriter.close()默认会 flush,一般无需额外调用
字节流与字符流嵌套的典型组合
常见合法嵌套结构及关闭要点:
-
读文本文件:
FileInputStream → InputStreamReader → BufferedReader→ 关BufferedReader -
写文本文件:
FileOutputStream → OutputStreamWriter → BufferedWriter→ 关BufferedWriter -
复制二进制文件:
FileInputStream → BufferedInputStream → FileOutputStream → BufferedOutputStream→ 关BufferedOutputStream和BufferedInputStream(二者无依赖,需都关,但用 try-with-resources 可并列声明)

















