如何在C中中断覆盖文件时避免丢失数据

How to avoid losing data when overwriting a file is interrupted in C

我已经编写了保存游戏进度的代码,但我最大的恐惧之一是保存期间的短暂 window 时间,如果计算机崩溃或断电,数据可能会损坏。

是否有仅使用 C 标准 I/O header 的标准方法,以确保先前的 save/file 如果程序在覆盖时崩溃时是安全的,不会留下临时文件?

算法

代码在1个文件中写入progress(t)、t和验证码(校验和、CRC等)。
下一次,代码将 progress(t+1), t+1 及其验证码写入另一个文件中。
重复以上两项。

要恢复,请阅读两个文件,当然至少有 1 个将具有有效的:进度、一些 t 和验证码。如果两者都好,则使用后者(更大的t)。

一个类似的想法结合了post的评论:
@Martin James

核心问题是 A) 有一个有效 "state" 文件之间存在时间间隔或 B) 有 2 个有效文件存在一个小间隔。因此,最坏的情况失败以使用 A 的 0 个文件和使用 B 的 2 个文件结束。显然 B 更可取。

写入状态 假设代码可能会在除 #1 之外的任何步骤之前、期间或之后崩溃。

  1. 假设存在初始状态(或进度)文件:State.txt.
  2. 如果存在,请删除较早的临时文件。 (客房服务)
  3. 在临时文件中写入新状态:State_tmp1.txt。要知道这个完成了,一些检查代码应该是"state"的一部分。此步骤可以与上一步合并为覆盖。
  4. 迂腐的步骤 - 可选。将 State_tmp1.txt 重命名为 State_tmp2.txt 以验证代码的 某些 方面具有重命名权限。
  5. State.txt 重命名为 State_tmp3.txt。这是关键的一步。到目前为止,任何失败都是无关紧要的,因为 State.txt 存在。在下一步完成之前,可能不存在 State.txt,但至少存在 1 个 tmp 文件。
  6. State_tmp1.txt 重命名为 State.txt。 (如果使用了步骤 4,则来自 State_tmp2.txt。)
  7. 删除 tmp 文件。

正在读取状态。

  1. 搜索 State.txt,如果发现 有效(通过有效性检查),继续执行步骤 3。
  2. 否则,寻找 tmp 文件并使用最新的有效文件。 (恢复状态的更多工作尚未详述。
  3. 清理 - 删除 tmp 文件。