【问题标题】:Is file overwriting in Java safe? [closed]Java中的文件覆盖安全吗? [关闭]
【发布时间】:2021-04-28 02:55:14
【问题描述】:

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

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

我想确保我的文件永远不会处于损坏状态。

【问题讨论】:

  • 您可以写入一个新文件,并在文件写入成功后重命名。
  • 我认为 100% 确定的唯一方法是在写入新文件之前备份您的文件,然后在完成后删除备份。如果备份存在,则在“重新启动”时询问用户是否要继续使用或从备份中恢复。
  • 我就是这么做的。
  • 您是在尝试防止数据在 SIGINT 事件期间被损坏(如 Linux 终端中的 ctrl+c),还是您在尝试处理意外关机?
  • 意外关机,但结果不是一样/不同的原因吗?

标签: java file overwrite


【解决方案1】:

如果应用程序在文件被覆盖时关闭,是否会丢失所有数据...

如果您只是在不采取任何预防措施的情况下写入文件,那么可以。

我想知道在 Java 中是否有任何内置方法可以做到这一点,就像有线程安全的类一样。

  1. Java 中没有内置方式。

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

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


我想确保我的文件永远不会处于损坏状态。

这是不可能的。

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

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

【讨论】:

  • 我很好,我不想确保我总是有最新的更新版本我知道这是不可能的,但我想找到一个解决方案来处理这种情况并返回以前的一。谢谢你的回答我找到了我的!
【解决方案2】:

我不知道 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,具体取决于中断发生的确切时间。

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

【讨论】:

  • 这就是我所做的,但我想知道在 Java 中是否有任何内置方法可以做到这一点,就像有线程安全的类一样。
  • 第 3 步应该是“将 important.xml.new 重命名为 important.xml。”因为复制可能是一个更复杂的操作,而重命名基本上只是更改标识符,因此不太可能被中断。它不一定是所有文件系统上的原子操作,但应该足够好。
  • 我想我会将新数据写入另一个文件,当第二个文件的写入完成时,第一个将被删除。在查找最后可用的数据时,如果应用程序找到两个文件,它将使用最旧的文件,因为这意味着在删除第一个文件之前发生了中断。我说的对吗?
猜你喜欢
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 2013-08-18
  • 2015-02-05
相关资源
最近更新 更多