繁体   English   中英

Java对象序列化,与ObjectOutPutStream一起使用后如何使用相同文件

[英]Java object serialization, how to use same file after using it with ObjectOutPutStream

我想将一个简单的类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进行序列化到文件中。 基本上,我希望代码能够执行以下操作:

        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)。 我尝试了刷新,重置等操作,但得到了另一个异常,但是它总是失败。 我怀疑这段代码中包含一些我不太了解的重要序列化概念,我希望有人帮助我对此有所了解。 我见过类似的问题,但答案似乎与我的问题不符。 如果我不想同时序列化所有对象,如何实现第一段代码的行为? 甚至更重要的是(为了提高我对序列化的理解),为什么这不起作用? 谢谢!

为此,您需要使用自定义类扩展ObjectOutputStream并重写writeStreamHeader方法。

您将需要找到一种方法来知道是否是第一次写入流(例如,使用历史记录文件:如果历史记录文件尚不存在,则为第一次,否则,您已经写入流中)。 第一次写入流时,将使用原始的ObjectOutputStream,然后还创建历史记录文件。

下次编写时,历史记录文件的存在使您知道它不是第一次,因此您使用自定义ObjectOutputStream类的实例并使用它写入流。 它不会写入标头,但会调用重置。 在这里查看更多

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM