ofstream(mode ios::out) 在系统停止时擦除现有文件空白

ofstream(mode ios::out) wipes existing file blank when system halt

使用场景为工业(unstable电源和其他buggyprograms/hardware)。要求程序在断电(或蓝屏死机)时不受影响地恢复。 OS 是 Windows 7 with NTFS。

我使用 boost::property_tree 写入 json 来将参数记录到人类可读的文本文件中。

boost::property_tree::write_json("logic.txt", pt);

它有时会在系统停止时擦除 "logic.txt"。 我阅读了 boost 源文件和 write_json 默认调用 ofstream ios::out

std::basic_ofstream<typename Ptree::key_type::value_type> stream(filename.c_str());        

问题应该是在系统出现故障时擦除现有文件并留下空白文件。

这是 ofstream 的已知问题吗?什么是最 suitable 的解决方案? 我能想到几个:

  1. 先将文件写入"logic_tmp.txt",完成后,删除"logic.txt"并将临时文件重命名为logic.txt。

  2. 使用 SQLite 而不是直接写入文件。 (MySQL 坏了几次,table 再次启动时需要 "repaired",SQLite 还没有让我失望)

任何建议都会有所帮助。

简单的解决方案是您的#1:写入一个临时文件然后重命名。但是,请注意,对于原子重命名,临时文件应该在同一个文件系统上。最安全的方法是将其简单地存储在同一目录中。当然,您可以使用 mkstemp() 或类似的方式来确保您拥有唯一的临时文件名。

以上仍然不是所有可能系统的 100% 保证,因为它取决于您的文件系统语义(您没有告诉我们您使用的是什么文件系统)。

如果你想要一个更可靠的解决方案,你的#2 是个好主意:使用 SQLite。它已经在您描述的许多场景中进行了测试。参见 https://www.sqlite.org/testing.html