我想将一个简单的类Person(名称和年龄)序列化为名为“somepersons.ser”的文件。基本上我想实现以下代码的行为:
Person p1 = new Person("Person1", 45);
Person p2 = new Person("Person2", 35);
FileOutputStream fos = new FileOutputStream("somepersons.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p1);
oos.writeObject(p2);
oos.close();
FileInputStream fis = new FileInputStream("somepersons.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
p1 = (Person)ois.readObject();
p2 = (Person)ois.readObject();
System.out.println(p1);
System.out.println(p2);
此代码将两个人员存储在一个文件中,然后在屏幕上恢复并显示它们。这可以按预期工作。
我的问题是:我想将存储Person的代码放在一个单独的方法中的文件中,因此您只需使用文件路径名和要序列化的Person作为参数调用该方法,并且该方法可以序列化传递的Person进入文件。基本上我希望代码可以做这样的事情:
Person p1 = new Person("Person1", 45);
Person p2 = new Person("Person2", 35);
FileOutputStream fos = new FileOutputStream("somepersons.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p1);
oos.close();
FileOutputStream fos2 = new FileOutputStream("somepersons.ser");
ObjectOutputStream oos2 = new ObjectOutputStream(fos2);
oos2.writeObject(p2);
oos2.close();
FileInputStream fis = new FileInputStream("somepersons.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
p1 = (Persona)ois.readObject();
p2 = (Persona)ois.readObject();
System.out.println(p1);
System.out.println(p2);
第二段代码尝试与第一段代码相同,但不依赖于已创建的FileOutputStream及其对应的ObjectOutputStream的存在。 但是当我尝试在ObjectInputStream上调用readObject时,它第二次引发了一个EOFException,因为只有一个对象被序列化了(第二个Person)。我试过刷新,重置等等,我得到了一个不同的异常,但总是失败。 我怀疑在这段代码中存在一些我不太了解的重要序列化概念,我希望有人能帮我解释一下。我见过类似的问题,但答案似乎不适合我的问题。如果我不想同时序列化所有对象,我怎么能实现第一段代码的行为?更重要的是(为了提高我对序列化的理解),为什么这不起作用? 谢谢!
答案 0 :(得分:0)
要按照您希望的方式执行此操作,您需要使用自定义类扩展ObjectOutputStream并覆盖writeStreamHeader方法。
您需要找到一种方法来了解您是否第一次写入流(例如,使用历史文件:如果历史文件尚不存在,那么这是第一次,否则你已经写过了流)。第一次使用原始ObjectOutputStream时写入流,然后还创建历史文件。
当您下次编写时,历史文件的存在会让您知道它不是第一次,因此您使用自定义ObjectOutputStream类的实例并使用它写入流。它不会写入标题但会调用重置。查看更多here