Java中如何仅当BufferedReader读取到有效数据时才创建文件,避免空文件
原代码的核心问题根源
当前实现会生成空文件的本质是提前初始化了文件写入流:new FileWriter(resultFile) 这个构造方法一旦执行,不管后续有没有写入数据,都会立刻在目标路径创建一个空的日志文件,哪怕读流的过程一行有效内容都没拿到,文件也已经落盘了。
调整实现的核心思路
把文件创建的时机延后:只有确认从进程输入流读到了第一行有效输出时,再初始化写入流、触发文件创建,如果整个流读完都没拿到任何数据,全程都不触碰目标文件,自然不会生成空文件。
具体实现步骤
- 先初始化读取进程输出的
BufferedReader流,这个操作和目标文件完全无关,不会触发文件创建。 - 用写入流本身的初始化状态作为判断标记,避免重复初始化逻辑。
- 在读循环中,首次读到非null的有效行时,再初始化
FileWriter和BufferedWriter——这一步才会真正触发空文件创建的动作。 - 所有读到的流内容正常写入到文件中,最后做好资源关闭,避免流泄漏。
参考实现代码
File resultFile = new File("/home/user/result.log"); BufferedWriter bw = null; // 用try-with-resources自动管理进程输入流的关闭,无需手动处理资源回收 try (BufferedReader stdInput2 = new BufferedReader(new InputStreamReader(process.getInputStream()))) { String line; while ((line = stdInput2.readLine()) != null) { // 首次读到有效数据时,再初始化文件写入逻辑 if (bw == null) { // 走到这里才会真正创建目标文件 bw = new BufferedWriter(new FileWriter(resultFile)); } bw.write(line + System.lineSeparator()); } } catch (IOException e) { // 按项目规范补充异常处理逻辑即可 } finally { // 只有写入流被初始化过,才需要执行关闭操作 if (bw != null) { try { bw.close(); } catch (IOException e) { // 按项目规范补充异常处理逻辑即可 } } }
补充注意事项
- 不要采用“先创建文件、读不到数据再删除文件”的替代方案:这种方式会产生冗余的磁盘IO,还可能因为目标路径权限不足、文件被其他进程占用等问题,出现删除失败残留空文件的情况。
- 这种延后初始化的逻辑不会改变原有的错误抛出时机:如果目标路径没有写入权限,只要读到第一行进程输出,就会和原逻辑一样抛出文件写入相关的权限异常,不会出现静默失败的问题。
- Java 7及以上版本可以直接用
System.lineSeparator()替代System.getProperty("line.separator"),写法更简洁,效果完全一致。
内容的提问来源于stack exchange,提问作者Thomazzz
相关产品推荐
相关产品推荐

