从单个文件反序列化多个对象
我有许多(同一类)的对象序列化到一个文件中。 但是在反序列化时,只反序列化了第一个序列化对象。
序列化代码:
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。