Java同一try-with-resources读写同文件致文件清空问题解析
问题根本原因
这个现象和try-with-resources语法本身无关,核心是FileWriter的默认行为+资源初始化时机错误:
- try-with-resources会严格按照括号内资源的声明顺序,从上到下执行初始化:先创建指向
configFile的BufferedReader,再创建指向同一个文件的BufferedWriter - 无append参数的
FileWriter默认以覆盖模式打开文件,只要其构造函数执行完成,就会直接把目标文件的长度截断为0,也就是立刻清空原文件所有内容 - 等你后续调用
br.readLine()读文件时,文件已经被刚初始化完成的写流清空,自然读不到任何内容。
调整后代码正常运行的逻辑
你修改后的写法完全避开了提前截断文件的问题:
- 第一阶段只打开读流,将文件全量内容读取到内存的
StringBuilder中,全程没有触发写文件操作,原文件内容不会被改动 - 等读取完成、确认目标参数存在后,才单独初始化写流。这时候虽然写流初始化依然会截断文件,但你已经把修改后的完整内容存在内存中,截断后直接写入即可,不会出现读空的问题。
原写法的额外风险
同时对同一个文件打开读写流本身就是不推荐的实践:
- 不同操作系统的文件锁策略不同,部分环境下会直接抛出「文件被占用」的IO异常
- 如果读取过程中发生异常,写流已经提前清空了原文件,会直接导致配置内容永久丢失,没有回滚余地
实践建议
修改小体积配置文件时,固定遵循「全量读入内存 -> 内存完成内容修改 -> 一次性覆盖写回」的流程,不要同时持有同一文件的读写流。如果是GB级大文件修改,建议先把内容写入同目录临时文件,等全部写入完成、校验无误后,再用临时文件替换原文件,避免写入中途异常导致原文件损坏。
内容的提问来源于stack exchange,提问作者RomanM
相关产品推荐
相关产品推荐

