C ++:如何正确实现文件以防止断电?

C++: How to correctly actualize a file against power loss?

我有一个 linux 嵌入式环境。

这里我有2个场景:

A:

  1. 打开并写入一个临时文件。
  2. 将临时文件重命名为原始文件。
  3. 断电

结果:重启后,我得到的是:

B:

  1. 打开并写入一个临时文件。

  2. FSYNC临时文件。

  3. 将临时文件重命名为原始文件。

  4. 断电

结果:重启后,

如您所见,在这两种情况下,唯一的区别是临时文件的fsync,而不是原始文件。在两者中,我 没有 fsync 原始文件

那么,为什么原文件的原始内容保留在方案B中?

从原始文件的角度来看,改变是,通过重命名非fsynced文件与fsynced文件来实现它。

如何保持原始内容?

编辑:

实现原始文件的场景也未能安全实现原始文件:

  1. 打开并写入一个临时文件。

  2. FSYNC 临时文件。

  3. 将临时文件重命名为原始文件。

  4. Fsync原文件目录

  5. 断电

结果:

0 大小的原始文件。

那么,我应该怎么做呢?

通常情况下,如果您想避免断电,您可以使用日记功能。这意味着(从广义上讲)你存储你想写的东西和你写的地方,当它成功写入时,你将它从日志中删除(至少在逻辑上)。如果出现重大故障(断电或其他系统崩溃),您可以阅读日志并应用仍然存在的任何更改。许多文件系统都有启用它的选项,在日志文件系统上,您可以期望重命名是原子的并且不受断电的影响:文件将以其以前的名称或新名称存在。

所以常见的工作流程是:

  • 将旧文件重命名为备份名称
  • 将新文件写入其最终名称
  • 关闭新文件以确保它将驻留在磁盘上
  • 删除备份文件(或给它一个不同的名称)

在断电(或任何其他崩溃情况)的情况下,下次重启时事情很简单:

  • 如果没有备份文件,则文件处于稳定状态
  • 如果存在备份文件,它包含文件的最后稳定状态:如果文件存在则必须将其删除并且必须将备份重命名为正常名称