Java序列化 - 在进程崩溃后恢复序列化文件

时间:2012-09-21 09:15:12

标签: java serialization crash objectinputstream

我有以下用例。

  • 进程使用BufferedOutputStream将某些对象序列化为文件。
  • 在编写每个对象后,进程调用flush()
  • 用例是如果进程在写入对象时崩溃,我想将文件恢复到已成功写入的上一个对象。

如何反序列化此类文件?在反序列化此类文件时,Java将如何表现。

  • 它会成功反序列化到崩溃前成功写入的对象吗?
  • 在阅读最后一个部分写入的对象时,行为是什么。我怎么能检测出来?

Update1 -

  • 我试图通过在写入对象时手动终止进程来模拟进程崩溃。我已经尝试了大约10-15次。每次我能够反序列化文件和文件没有任何部分对象。

我不确定我的测试是否足够详尽,因此需要进一步的建议。

Update2 - Adam指出了一种方法,可以使用随机截断文件来模拟此类测试。 以下是尝试进行大约100次迭代时观察到的行为 -

  • 从截断的文件(应该等同于进程崩溃时的文件条件),Java可以成功读取最后一个完整对象。
  • 在到达最后一个部分写入的对象时,Java不会抛出任何StreamCorruptedExceptionIOException。它只会抛出EOFException指示EOF并忽略部分对象。

4 个答案:

答案 0 :(得分:2)

在阅读下一个对象之前,是否对每个对象进行反序列化。它不会受到影响,因为后来的对象编写失败或无法反序列化

答案 1 :(得分:1)

我怀疑你是在滥用java序列化 - 它并不是一种可靠且可恢复的永久存储方式。使用数据库。如果必须,你可以 使用数据库来存储java对象的序列化形式,但这样效率很低。

答案 2 :(得分:0)

是的,手动测试这种情况(通过终止进程)可能很困难。我建议你写一个测试用例:

  1. 序列化一组对象并将其写入文件。
  2. 打开文件,基本上将其截断为随机位置。
  3. 尝试加载和反序列化(并查看会发生什么)
  4. 重复1.到3.以及其他几个截断位置。
  5. 通过这种方式,您确定要加载损坏的文件并且代码正确处理它。

答案 3 :(得分:-1)

您是否尝试过附加到ObjectOutputStream?您可以找到解决方案HERE,只需找到解释如何使用append创建ObjectOutputStream的帖子。