java - 从文件中读取多个对象,就像它们在数组中一样

use*_*407 5 java object

我想请问社区,您对以下情况有何看法。任务是将对象写入文件。这可以通过将对象列表写入文件来实现,稍后我可以读取该文件,以便我再次拥有我的对象。在这里,我实际上只会将一个对象写入文件,即列表(可能包含更多对象)。

但是,任务接缝是将单独的对象写入文件,该方法从列表中接收该文件。对象可以是任何东西。(当然它们必须是可序列化的)

所以我做了:

public class TaskStream {
    public static void saveObjects(ArrayList<Object> al) {
        try {
            FileOutputStream fos = new FileOutputStream("outputFile", true);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                for (Object o : al){
                    try {
                        oos.writeObject(o);
                        System.out.println("saved");
                    } catch (NotSerializableException e) {
                        System.out.println("An object was not serializable, it has not been saved.");
                        e.printStackTrace();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
Run Code Online (Sandbox Code Playgroud)

这工作得很好。

但现在,我想阅读它们。我关于它的第一个概念是一种方法,它读取对象直到文件中有对象,然后我可以将它们中的每一个再次保存到列表中(这就是任务)。所以像伪代码:

for(Object o : fileToRead){ list.add(o) }
Run Code Online (Sandbox Code Playgroud)

怎么可能?我开始尝试使用 ObjectInputStream 的 readObject 方法,但它似乎导致了很多错误。

你有什么主意吗?或者这样的任务的最佳实践是什么?


谢谢!

我尝试了你的想法。具体实现:

public static ArrayList<Object> readObjects(){
    ArrayList<Object> al = new ArrayList<Object>();
    boolean cont = true;
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("outputFile"));
            while(cont){
                  Object obj=null;
                try {
                    obj = ois.readObject();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                  if(obj != null)
                     al.add(obj);
                  else
                     cont = false;
               }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 return al;
}    
Run Code Online (Sandbox Code Playgroud)

为了测试程序,我将向文件中写入两个对象。我从文件中读取对象并将它们添加到列表中。我遍历这个列表并打印出内容。

如果我运行该程序,则会发生以下情况(我删除了 outputFile,因此程序可以重新创建它并从头开始执行所有操作)。

结果:

列表中的两个对象将被成功打印。但我收到这个:

java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2598)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1318)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)    
Run Code Online (Sandbox Code Playgroud)

...

我没有改变任何东西,我再次运行程序。结果:

列表中的两个对象将被成功打印。但我收到这个:

java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1377)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)    
Run Code Online (Sandbox Code Playgroud)

从现在开始,任何重新运行都会带来相同的结果。

如果我再次从头开始重复整个过程(从删除 outputFile 开始),一切都会完全相同(如预期的那样)。

你有解决方法的想法吗?非常感谢你的帮助!

Mit*_*man 5

您将要使用 FileInputStream 和 ObjectInputStream。

FileInputStream fis = new FileInputStream("outputFile");
ArrayList<Object> objectsList = new ArrayList<>();
boolean cont = true;
while (cont) {
  try (ObjectInputStream input = new ObjectInputStream(fis)) {
    Object obj = input.readObject();
    if (obj != null) {
      objectsList.add(obj);
    } else {
      cont = false;
    }
  } catch (Exception e) {
    // System.out.println(e.printStackTrace());
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 你永远不会关闭输入。 (3认同)
  • 这不会达到比较 - 在​​ readObject() 抛出异常 - 在循环内捕获 IOException (3认同)