是否可以安全地覆盖保存文件?

时间:2013-08-15 20:09:19

标签: c++ file save

使用cstdio,覆盖文件最安全的方法是什么?在这种情况下,“安全”意味着文件不可能变得不完整或被破坏;该文件将被完全覆盖,或者如果出现问题,它将是旧文件。

我想最好的方法是创建一个临时的中间文件,然后在中间文件完成后覆盖旧文件。如果这实际上是最好的方式,那么其他一些问题似乎是可能的,如果这种问题很少见。

  • 如果程序在覆盖时退出,我怎么知道使用这个其他文件?
  • 如果程序在创建过程中退出,我怎么知道不使用其他文件?
  • 我怎么知道原始文件或 中间体处于未定义状态(因为它可能会失败) 仍然可读,但它包含的数据是巧妙的错误)?

我想有一个好的做法,但我找不到它。这是为了保存的游戏数据;只有一个文件,每次都会覆盖整个文件,没有部分覆盖或者担心。

3 个答案:

答案 0 :(得分:4)

正如其他人所说,保留现有文件,并写入新文件。如果它非常重要(也就是说,用户无法恢复信息),请确保周围还有“备份”文件(例如,如果您的程序保存abc.config,请留下{{1} }或abc.old.config [如果您希望保证名称可以在任何地方使用,abc.backup.cfg可能是更好的选择]。

编写文件时,在文件中放置某种终结符,以便确保文件完整。如果要避免对文件进行“用户编辑”,您可能还需要对内容(sha1,md5或类似内容)进行校验和。如果终结器不在那里,或者校验和错误,那么你就知道文件是“坏”的,所以不要使用它。去备份。

  1. 将新内容写入临时文件(例如.bak
  2. 删除备份文件(如果存在)(例如fstream fout("abc.tmp");
  3. 将现在的旧文件重命名为备用名称(例如remove("abc.bak");
  4. 将新文件重命名为旧文件(例如rename("abc.cfg", "abc.bak"););
  5. 对于所有步骤(特别是写入实际数据),检查错误。您需要确定错误的位置和错误的位置(例如,不存在的文件的rename("abc.tmp", "abc.cfg"是正常的,但如果remove不起作用,您可能应该停止,或者你可能最终得到一些不好的东西)。

    加载文件时,请检查所有步骤,如果出错,请返回备份文件。

答案 1 :(得分:1)

您应该使用数据库管理系统来保证ACID。如果您坚持使用平面文件,则应写入临时文件,在写入完成时复制并替换实际文件,并仅在复制成功时删除临时文件。此外,每次写入文件时都要调用flush()

答案 2 :(得分:-1)

您应该在将数据保存到文件时阻止关闭应用程序。你应该做的是加载旧文件,将其保存在变量中 - 覆盖变量的数据(在你的应用程序中),并将其写在旧文件上。 一切都应该不到1秒,所以你不必担心在保存时关闭你的应用程序。 此外,仅在检查操作是否可行且数据完整性是否正确后才覆盖。