try-with-resources读写文件的核心是将所有实现AutoCloseable的流(如FileReader、BufferedReader、FileWriter、BufferedWriter)声明在try括号内,JVM自动逆序关闭,异常时主异常优先抛出、关闭异常被抑制并可追溯。

用 try-with-resources 读写文件,核心就一条:把所有实现了 AutoCloseable 的流对象(比如 FileReader、FileWriter、BufferedReader、BufferedWriter)直接声明在 try 括号里。JVM 会确保它们在作用域结束时自动关闭,哪怕中间抛了异常也不会漏关。
读文件:推荐用 BufferedReader + FileReader 组合
单靠 FileReader 效率低、不支持按行读;加一层 BufferedReader 更实用,也更安全:
- 两个类都实现
AutoCloseable,可以一起放进 try 括号 - 关闭顺序是“后声明先关”——
BufferedReader先关,再关底层FileReader,避免操作已释放句柄 - 不用手动调
close(),也不用判空或写finally
示例代码:
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("读取失败:" + e.getMessage());
}
写文件:优先用 BufferedWriter + FileWriter
FileWriter 默认覆盖写,若需追加,构造时传 true;加 BufferedWriter 能提升写入性能,并支持 newLine():
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 同样支持多资源声明,关闭时自动逆序执行
- 关键点:如果写的是重要数据(如配置、日志),建议在
try块末尾显式调用flush(),提前暴露磁盘满、权限不足等问题 -
close()本身会触发flush(),但显式调用能让错误更早暴露
示例代码(追加写):
try (FileWriter fw = new FileWriter("output.txt", true);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write("新一行内容");
bw.newLine();
bw.flush(); // 主动刷新,确认写入成功
} catch (IOException e) {
System.err.println("写入失败:" + e.getMessage());
}
读写同时操作:别套娃,分开声明更清晰
比如从一个文件读、写到另一个文件,不要用 new BufferedReader(new FileReader(...)) 这种嵌套初始化方式——外层流没被 try 管理,容易泄漏:
- 正确做法:两个流都独立声明在同一个 try 括号里,用分号隔开
- 系统按逆序关闭,先关
BufferedWriter,再关BufferedReader,逻辑干净 - 即使读或写中途出错,另一个流仍会被正常关闭
示例代码:
try (FileReader fr = new FileReader("source.txt");
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter("target.txt");
BufferedWriter bw = new BufferedWriter(fw)) {
String line;
while ((line = br.readLine()) != null) {
bw.write(line.toUpperCase());
bw.newLine();
}
} catch (IOException e) {
System.err.println("IO 操作异常:" + e.getMessage());
}
异常处理:主异常优先,关闭异常可追溯
如果 try 块里抛了异常,同时某个 close() 也失败了,JVM 会:
- 把
try块的异常作为主异常抛出 - 把
close()异常添加为 suppressed exception(被抑制异常) - 可通过
e.getSuppressed()获取,适合排查“为什么文件明明写了却没落盘”这类问题
调试时可加一句打印:
} catch (IOException e) {
System.err.println("主错误:" + e.getMessage());
for (Throwable suppressed : e.getSuppressed()) {
System.err.println("被抑制的关闭错误:" + suppressed.getMessage());
}
}

















