Java代码出现资源泄漏警告且friends.txt文件无法写入如何解决?
问题原因及修复方案
1. 资源泄漏警告原因
你的流关闭逻辑仅在try块正常执行完成时才会触发,若执行过程中抛出异常、或者readFriends方法中else分支直接return new ArrayList<>(),已打开的流没有执行close操作,就会触发资源泄漏警告。
2. 写文件无输出的问题原因
- 路径格式错误:Java字符串中
\是转义字符,直接写C:\Users\aa\Desktop\src\friends.txt会被识别为非法转义,要么改为双反斜杠C:\\Users\\aa\\Desktop\\src\\friends.txt,要么用跨平台的正斜杠C:/Users/aa/Desktop/src/friends.txt。 - 序列化缺失:用
ObjectOutputStream写自定义对象时,Friend类必须实现Serializable接口,否则会抛出序列化异常。你当前catch块仅打印固定提示没有输出异常栈,无法感知到这类错误。 - 流关闭逻辑风险:旧代码中如果写数据过程中抛异常,流不会关闭,缓冲区的数据没来得及flush到文件,也会导致文件无内容。
3. 读方法隐藏逻辑bug
你当前的读逻辑中,先读取了一次size:int size = friendReader.readInt();,后续循环条件又重复读取了一次int:for (int i = 0; i < friendReader.readInt(); i++),会导致读取位置错位,无法正确读取后续的Friend对象。
修复方案
使用Java 7及以上支持的try-with-resources语法,无需手动写close,流会在try块结束后自动关闭,不管是否发生异常,从根源解决资源泄漏问题;同时修正路径、读逻辑、补全异常排查逻辑,修复后代码如下:
import java.io.*; import java.util.ArrayList; public class ReadWrite { public void writeFriends(ArrayList<Friend> friends) { // 先校验路径的父目录是否存在,不存在则创建 File file = new File("C:/Users/aa/Desktop/src/friends.txt"); file.getParentFile().mkdirs(); // try-with-resources自动关流 try (FileOutputStream friendFile = new FileOutputStream(file); ObjectOutputStream friendWriter = new ObjectOutputStream(friendFile)) { if(friends.size() >0) { friendWriter.writeInt(friends.size()); for (Friend friend : friends) { friendWriter.writeObject(friend); } } else { System.out.println("No data to write"); } } catch (FileNotFoundException e) { System.out.println("File Not Found. Retry after creating File 'Friends.txt'"); e.printStackTrace(); } catch (IOException e) { System.out.println("Stream cannot be initialized."); e.printStackTrace(); } } public ArrayList<Friend> readFriends() { ArrayList<Friend> friends = new ArrayList<>(); File file = new File("C:/Users/aa/Desktop/src/friends.txt"); try (FileInputStream friendFile = new FileInputStream(file); ObjectInputStream friendReader = new ObjectInputStream(friendFile)) { int size = friendReader.readInt(); if(size > 0){ // 循环直接用已读取的size,不要重复readInt for (int i = 0; i < size; i++) { friends.add((Friend) friendReader.readObject()); } } else{ System.out.println("Empty File"); } } catch (FileNotFoundException e) { System.out.println("File Not Found. Retry after creating File 'Friends.txt'"); e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { System.out.println("Stream cannot be inititalized"); e.printStackTrace(); } return friends; } }
另外注意:ObjectOutputStream写入的是二进制序列化数据,即使你用txt作为后缀,直接打开文件看是乱码属于正常现象,只要读方法能正常取出Friend对象即代表写入成功。
内容的提问来源于stack exchange,提问作者user9630935
相关产品推荐
相关产品推荐

