java中try-with-resources配合bufferedreader是推荐的文件读取方式,需在try括号内直接声明初始化以确保自动关闭;多层流应显式声明所有资源,避免句柄泄漏,并注意编码与资源重赋值问题。

Java 中 try-with-resources 配合 BufferedReader 是最常见也最推荐的文件读取方式,核心在于让资源自动释放、避免句柄泄漏,同时保持代码简洁可靠。
必须确保 BufferedReader 在 try 括号内声明并初始化
不能只把 BufferedReader 声明在外部再传入 try 块——它必须是 try 后圆括号中直接创建的对象,且类型需实现 AutoCloseable(BufferedReader 已满足):
- ✅ 正确写法:资源生命周期完全由 JVM 管控
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
- ❌ 错误写法:外部创建 + 仅传入引用 → 底层
FileReader可能未关闭
FileReader fr = new FileReader("data.txt");
BufferedReader br = new BufferedReader(fr);
try (br) { // Java 9+ 允许,但前提是 fr 和 br 都是 effectively final
// ...
}
注意:Java 9 起支持已声明的 effectively final 变量(如上例中的 br),但此时仍要确认其底层资源(如 FileReader)是否也被纳入管理;否则仍有泄漏风险。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
多层流嵌套时,建议显式声明所有关键资源
当用 BufferedReader 包装 FileReader 或 InputStreamReader 时,若想确保每层都安全关闭,推荐在同一个 try 括号中一并声明:
- 资源按“后声明先关闭”顺序执行,所以
BufferedReader会先关,再关FileReader - 即使
BufferedReader.close()内部已调用底层close(),显式声明更稳妥、语义更清晰
try (FileReader fr = new FileReader("data.txt");
BufferedReader br = new BufferedReader(fr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
异常处理要注意被抑制异常(suppressed exceptions)
如果 br.readLine() 抛出异常,且后续 br.close() 也失败,JVM 会把 close 异常作为“被抑制异常”附加到主异常上:
- 主异常可通过
e.printStackTrace()显示原始错误 - 被抑制异常需用
e.getSuppressed()显式获取,适合做日志追踪 - 不必手动捕获 close 过程中的异常,这是 try-with-resources 的设计优势
实际使用中的几个关键提醒
-
BufferedReader必须搭配字符流(如FileReader或InputStreamReader),不能直接包装字节流(如FileInputStream) - 若需指定编码(如 UTF-8),应使用
InputStreamReader替代FileReader,因为后者默认使用平台编码 - 不要在 try 块内对资源变量重新赋值(例如
br = null或br = new BufferedReader(...)),会导致原始资源引用丢失,无法关闭
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










