2011-12-04 37 views
0

我有许多对象(同一类)被序列化为一个文件。 但是,当它反序列化时,只有第一个序列化的对象被反序列化。反序列化单个文件中的多个对象

代码序列化:

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) 

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

+0

你能展示如何序列化对象到文件吗?看起来你正在做一个自定义的序列化过程。 –

+2

你不会说你的问题实际上是什么,并且看到你如何捕捉并抛弃异常,你不可能说出它是什么。 – kdgregory

+0

ObjectOutputStream不会生成文本文件。它是二进制的。 – EJP

回答

1

最好在开始时写入文件中的Vehicule数量,并让它控制您读取的数量。

如果你想这样做你正在做的方式,那么你将不得不尝试/捕获一个IOException异常

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

+0

使用反序列化对象的数量不会有帮助。只有第一个对象被打印 –

+0

或者序列化一个List TJR

1

如果你是要使用多个附加ObjectOutputStreams,那么我相信this可能帮助(确保你每次运行测试时间删除文件一起!):

为什么不能包含多个附加ObjectOutputStreams是文件被一个Obje反序列化ctInputStream?

使用序列的默认实现,必须有ObjectOutputStream建设和 ObjectInputStream建设之间的 一个一对一的映射。 ObjectOutputStream构造函数 写入流标题并ObjectInputStream读取此流 标题。解决方法是子类ObjectOutputStream并覆盖 writeStreamHeader()。首要writeStreamHeader()应该 调用超级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 
+0

我试过用ArrayList。没有工作 –

+0

现在你已经添加了序列化代码,它看起来像你在'Vehicule'类('oos.writeObject(this);')上实现了save()方法。要序列化为List,您必须序列化该类之外的所有Vehicules(在一个方法调用中)。 –

+0

@NiceBooks定义“没有工作”。 – EJP

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) 

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

在EOS,Javadoc没有任何关于readobject()返回null的信息。 readObject()返回null当且仅当你写了null

正确的方法是捕捉EOFException,关闭流并跳出循环。

0

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

0

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