从单个文件反序列化多个对象

时间:2011-12-04 23:07:59

标签: java deserialization

我有许多(同一类)的对象序列化到一个文件中。 但是在反序列化时,只反序列化了第一个序列化对象。

序列化代码:

public void save() {
File f = new File("vehicule.txt");
try {
    if(!f.exists()) f.createNewFile();
} catch(IOException e) {
}
try {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f,true));
oos.writeObject(this);
} catch(IOException e) {
}

}

我认为问题在于:

Vehicule v;
while( (v = (Vehicule)ois.readObject()) != null )

有没有更好的方法来检查文件的结尾?

5 个答案:

答案 0 :(得分:1)

最好先编写文件中的Vehicule数量,然后控制你读取的数量。

如果你想按照你的方式去做,那么你将不得不尝试/捕获IOException

[也顺便说一下,这不是一个txt文件]

答案 1 :(得分:1)

如果您打算使用多个附加的ObjectOutputStreams,那么我相信this可能有所帮助(同时确保每次运行测试时都删除该文件!):

  

为什么包含多个附加的ObjectOutputStream的文件不能被一个ObjectInputStream反序列化?

     

使用序列化的默认实现,必须有一个   ObjectOutputStream构造与构造之间的一对一映射   ObjectInputStream建设。 ObjectOutputStream构造函数   写入流标头,ObjectInputStream读取此流   头。解决方法是子类ObjectOutputStream并覆盖   writeStreamHeader()。最重要的writeStreamHeader()应该   如果是第一次写入,则调用super writeStreamHeader方法   该文件,如果是,则应调用ObjectOutputStream.reset()   附加到文件中预先存在的ObjectOutputStream

否则我建议您将对象添加到List,然后使用单个ObjectOutputStream对其进行序列化。

例如:

    Vehicule v1 = new Vehicule();
    Vehicule v2 = new Vehicule();
    List<Vehicule> vehicules = Arrays.asList(v1, v2);

    // serialize the list of Vehicules
    File f = new File("vehicule.txt");
    try {
        ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(f));
        oos.writeObject(vehicules);
        oos.close();
    } catch (Exception e) {
        e.printStackTrace(); // handle this appropriately
    }

    // deserialize the list of Vehicules
    try {
        ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(f));
        List<Vehicule> deserializedVehicles = (List<Vehicule>) ois.readObject();
        ois.close();
        System.out.println("list size = " + deserializedVehicles.size());
    } catch (Exception e) {
        e.printStackTrace(); // handle this appropriately
    }

对我来说,这会输出:

list size = 2

答案 2 :(得分:0)

try {
    if(!f.exists()) f.createNewFile();
} catch(IOException e) {
}

你不需要任何这些。 new FileOutputStream()将创建该文件。

new ObjectOutputStream(new FileOutputStream(f,true))

您无法附加到ObjectOutputStream。如果ObjectInputStream在流中间遇到它们,则会有while( (v = (Vehicule)ois.readObject()) != null ) 无法理解的标题。

readobject()
  

有没有更好的方法来检查文件的结尾?

Javadoc中没有关于null在EOS返回readObject()的内容。当且仅当您撰写null时,null才会返回EOFException

正确的方法是捕获{{1}},关闭流,然后突破循环。

答案 3 :(得分:0)

只需序列化/ deserlialize ArrayList<Vehicle>(而不是尝试将多个对象填充到单个文件中)。

答案 4 :(得分:0)

好的,这就是它最终的运作方式。
我将文件中的所有内容反序列化为ArrayList;添加了新对象,在序列化时,我将ArrayList的每个元素添加到文件中[使用(new FileOutputStream(new File("Vehicule.txt"),false)]删除以前的条目。
最后,我明确地向文件中添加了一个null,以帮助进行反序列化 在使用createNewFile第一次创建文件时,我在文件中添加了一个空值。