Java 中的文件覆盖安全吗?

Is file overwriting in Java safe?

我应该遵循什么模式来正确处理 Java 中某些数据序列化过程中软件突然关闭的风险?

假设我有一些要更新的数据文件。如果应用程序在覆盖文件时关闭,是否有可能丢失所有数据,或者 Java 是否有防止这种情况发生的机制?

我想确保我的文件永远不会以损坏的状态结束。

我不知道 Java 是否有任何机制可以防止断电时数据损坏,但您可以按照步骤将影响降至最低。

假设您有一个要写入的名为 important.xml 的文件。你可以这样做:

  1. important.xml 复制为 important.xml.old
  2. 将新数据写入important.xml.new
  3. important.xml.new复制到important.xml
  4. 删除important.xml.old.

这样一来,如果在此过程中断电,那么在 important.xmlimportant.xml.old 中总会有至少一份旧数据,具体取决于断电的确切时间发生中断。

然后您可以添加日志记录以确定中断发生的确切时间,以便您可以在必要时恢复数据。

Is it possible that all data gets lost if the application shuts off while the file is being overwritten ...

如果您只是简单地写入文件而没有采取任何预防措施,那么可以。

I wanted to know if there were any built-in ways to do it in Java, just like there are Thread-safe classes.

  1. Java没有内置方法。

  2. 这不是线程安全问题。例如,即使是线程安全的程序也不能保证在 JVM 收到 kill -KILL 信号时它会正常工作。

假设,如果 Java 可以假定典型的文件系统支持跨文件操作的事务,则此 可以 以“内置”方式解决多个文件和目录。虽然这种文件系统的例子确实存在,但它们不是主流。有关事务文件系统主题的更多信息,请参阅 this page


I want to make sure my files never end up in a corrupted state.

那是不可能的。

话虽如此,如果您的应用程序正确实施了@ekolis 的方案1,它不会在重新启动时看到损坏的文件...除非损坏是由文件引起的系统或外部代理2。实际上,应用程序可能能够检测到更新正在进行,甚至可以恢复“丢失”的更改。 (虽然您可能不想自动执行此操作......如果没有用户的“这么说”。)

1 - 例如,您需要进行原子重命名而不是复制,建议在重命名之前强制文件系统 'sync'。
2 - 没有应用程序可以防止文件系统损坏或其他一些“外部代理”弄乱文件。它依赖于 OS 来执行此操作,即使正确实施 OS 在某些情况下也无法防止数据丢失。