首页 > 解决方案 > 资源泄漏和输出文件未写入

问题描述

我在return new ArrayList<>();. 该文件未写入我试图将列表保存在文本文件中的 friends.txt 中。请帮忙。

import java.io.*;
import java.util.ArrayList;

public class ReadWrite {

    public void writeFriends(ArrayList<Friend> friends) {
        FileOutputStream friendFile;
        ObjectOutputStream friendWriter;
        try {
            friendFile = new FileOutputStream(new File("C:\\Users\\aa\\Desktop\\src\\friends.txt"));
            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");
            }
            friendWriter.close();
            friendFile.close();

        } catch (FileNotFoundException e) {
            System.out.println("File Not Found. Retry after creating File 'Friends.txt'");
        } catch (IOException e) {
            System.out.println("Stream cannot be initialized.");
        }
    }

    public ArrayList<Friend> readFriends() {
        FileInputStream friendFile;
        ObjectInputStream friendReader;
        ArrayList<Friend> friends = new ArrayList<>();
        try {
            friendFile = new FileInputStream(new File("C:\\Users\\aa\\Desktop\\src\\friends.txt"));
            friendReader = new ObjectInputStream(friendFile);
            int size = friendReader.readInt();
            if(size > 0){
                for (int i = 0; i < friendReader.readInt(); i++) {
                    friends.add((Friend) friendReader.readObject());
                }
            }
            else{
               System.out.println("Empty File");
               return new ArrayList<>();
            }
            friendReader.close();
            friendFile.close();

        } catch (FileNotFoundException e) {
            System.out.println("File Not Found. Retry after creating File 'Friends.txt'");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("Stream cannot be inititalized");
        }
        return friends;
    }
}

我正在尝试将朋友列表保存在 friends.txt 文件中。我在friends.txt 文件中看不到任何输出。这与我的位置有关FileOutputStream吗?

标签: java

解决方案


您的代码中有两个问题。

  1. for方法的循环中有一个错误。readFriendsReadWrite
  2. 文件friends.txt可能未关闭。

这是更正后的代码。请注意,我在您的问题中找不到类的代码,Friend所以我写了一个最小的类。由于您使用的是序列化,我假设该类Friend实现接口Serializable

代码后的注释。

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;

public class ReadWrite {
    public void writeFriends(ArrayList<Friend> friends) {
        try (OutputStream friendFile = Files.newOutputStream(Paths.get("C:", "Users", "aa", "Desktop", "src", "friends.dat"));
             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.dat'");
            e.printStackTrace();
        }
        catch (IOException e) {
            System.out.println("Stream cannot be initialized.");
            e.printStackTrace();
        }
    }

    public ArrayList<Friend> readFriends() {
        ArrayList<Friend> friends = new ArrayList<>();
        try (InputStream friendFile = Files.newInputStream(Paths.get("C:", "Users", "aa", "Desktop", "src", "friends.dat"));
             ObjectInputStream friendReader = new ObjectInputStream(friendFile)) {
            int size = friendReader.readInt();
            if (size > 0) {
                for (int i = 0; i < size; i++) {
                    friends.add((Friend) friendReader.readObject());
                }
            }
            else {
                System.out.println("Empty File");
                return new ArrayList<>();
            }
        }
        catch (FileNotFoundException e) {
            System.out.println("File Not Found. Retry after creating File 'friends.dat'");
            e.printStackTrace();
        }
        catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            System.out.println("Stream cannot be inititalized");
            e.printStackTrace();
        }
        return friends;
    }

    public static void main(String[] args) {
        ArrayList<Friend> friends = new ArrayList<>();
        Friend friend = new Friend("Jane");
        friends.add(friend);
        ReadWrite rw = new ReadWrite();
        rw.writeFriends(friends);
        ArrayList<Friend> newFriends = rw.readFriends();
        System.out.println(newFriends);
    }
}

class Friend implements Serializable {
    private String name;

    public Friend(String name) {
        this.name = name;
    }

    public String toString() {
        return name;
    }
}

for方法中的循环条件中,readFriends您具有以下内容:

friendReader.readInt()

这意味着在每次循环迭代中,您都试图int从文件中读取另一个friends.txt。此调用失败,因为文件中只有一个int。因此,您需要使用sizewhich 是包含您在循环之前读取的唯一intin 文件的变量。friends.txtfor

由于您使用的是序列化,因此建议为文件名提供扩展名,.dat而不是.txt因为文件不是文本文件。

我总是写printStackTrace()在我的catch块中,因为这有助于我找到异常的原因。您实际上不应该得到 a FileNotFoundException,因为如果文件不存在,Java 将创建该文件。如果 Java 无法创建文件,那么可能是因为用户没有创建文件的权限,因此显示一条错误消息说在运行代码之前创建文件可能无济于事。

您的代码可能会成功打开文件并向其中写入一些数据并在您写入所有数据之前崩溃。在这种情况下,您的代码不会关闭该文件。如果您至少使用 Java 7,那么您应该使用try-with-resources来确保文件始终关闭。

Java 7 还引入了NIO.2作为更好的 API,用于从 Java 代码与计算机的文件系统进行交互。我建议您按照我在上面的代码中显示的那样使用它。


推荐阅读