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

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

序列化代码:

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 ) 

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

最好在开头编写文件中的Vehicule数量,并控制你读取的数量。

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

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

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

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

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

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

例如:

  Vehicule v1 = new Vehicule(); Vehicule v2 = new Vehicule(); List 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 deserializedVehicles = (List) ois.readObject(); ois.close(); System.out.println("list size = " + deserializedVehicles.size()); } catch (Exception e) { e.printStackTrace(); // handle this appropriately } 

对我来说,这输出:

 list size = 2 
 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 ) 

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

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

正确的技术是捕获EOFException ,关闭流,并打破循环。

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

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