问题描述
我应该遵循什么模式来正确处理在 Java 中某些数据序列化过程中软件关闭的风险?
假设我有一些数据文件要更新。如果在覆盖文件时应用程序关闭,是否有可能所有数据都丢失,或者 Java 是否有防止这种情况发生的机制?
我想确保我的文件永远不会处于损坏状态。
解决方法
如果在覆盖文件时应用程序关闭,所有数据是否可能丢失...
如果您只是在没有采取任何预防措施的情况下写入文件,那么是。
我想知道在 Java 中是否有任何内置方法可以做到这一点,就像有线程安全的类一样。
-
Java 中没有内置方法。
-
这不是线程安全问题。例如,即使是线程安全的程序也不能保证在 JVM 收到
kill -KILL
信号时它会正常工作。
假设,如果 Java 可以假设典型的文件系统为跨多个文件和目录的文件操作的事务提供支持,那么这个可以以“内置”方式解决。虽然这种文件系统的例子确实存在,但它们不是主流。有关事务性文件系统主题的详细信息,请参阅 this page。
我想确保我的文件永远不会处于损坏状态。
这是不可能的。
话虽如此,如果您的应用程序正确实现了@ekolis 的方案1,它不会在重新启动时看到损坏的文件...除非损坏是由文件系统或外部代理引起的2。实际上,应用程序可能能够检测到正在进行的更新,甚至可以恢复“丢失”的更改。 (尽管您可能不希望自动执行此操作……没有用户的“这么说”。)
1 - 例如,您需要进行原子重命名而不是复制,并且建议在重命名之前强制文件系统“同步”。
2 - 没有应用程序可以防止文件系统损坏,或其他一些“外部代理”弄乱文件。它依赖于操作系统来做到这一点,即使是正确实施的操作系统在某些情况下也无法防止数据丢失。
我不知道 Java 是否有任何机制可以在断电时防止数据损坏,但您可以按照步骤将影响降至最低。
假设您有一个名为 important.xml
的文件要写入。你可以这样做:
- 将
important.xml
复制为important.xml.old
。 - 将新数据写入
important.xml.new
。 - 将
important.xml.new
复制到important.xml
。 - 删除
important.xml.old
。
这样,如果在此过程中断电,则始终至少有一个旧数据的副本,在 important.xml
或 important.xml.old
中,具体取决于断电的确切时间.
然后您可以添加日志来确定中断发生的确切时间,以便您可以在必要时恢复数据。