gpt4 book ai didi

c++ - 覆盖文件而不会有损坏文件的风险

转载 作者:IT王子 更新时间:2023-10-29 00:35:56 27 4
gpt4 key购买 nike

我的应用程序经常想要保存文件以便稍后再次加载。最近因崩溃而倒霉,我想以这样一种方式编写操作,以保证我拥有新数据或原始数据,但没有损坏的困惑。

我的第一个想法是按照以下方式做一些事情(保存一个名为 example.dat 的文件):

  1. 为目标目录想出一个唯一的文件名,例如example.dat.tmp
  2. 创建该文件并将我的数据写入其中。
  3. 删除原文件(example.dat)
  4. 将临时文件重命名(“移动”)到原始文件所在的位置(example.dat.tmp -> example.dat)。

然后在加载时应用程序可以遵循以下规则:

  • 如果没有“example.dat”和“example.dat.tmp”,首先运行/新项目,加载默认值/创建新文件。
  • 如果“example.dat”且没有“example.dat.tmp”,则加载 example.dat(正常加载情况)
  • 如果“example.dat.tmp”存在,则为用户提供恢复数据的机会。如果“example.dat”也存在,不要在没有显式用户常量的情况下覆盖它。

然而,在做了一些研究后,我发现除了我可以用文件刷新方法覆盖的操作系统缓存外,一些磁盘驱动器仍然在内部缓存,甚至可能欺骗操作系统说它们已完成,所以 4. 可以完成,写入实际上并没有写入,如果系统出现故障,我将丢失数据...

我不确定磁盘问题是否真的可以通过应用程序解决,但上面的一般规则是否正确?我是否应该将文件的旧恢复拷贝保留更长时间才能确定,关于此类事情的准则是什么(例如,可接受的磁盘使用情况、用户是否应该选择、将此类文件放在哪里等)。

还有我应该如何避免用户和其他程序对“example.dat.tmp”的潜在冲突。我记得有时会在其他软件中看到“~example.dat”,这是更好的约定吗?

最佳答案

如果磁盘驱动器向操作系统报告数据是物理上在磁盘上,它不是,那么你就没有多少可以做些什么。很多磁盘确实缓存了一定数量的写入并报告它们已完成,但是这样的磁盘应该有备用电池,无论如何都要完成物理写入(而且他们不会在系统崩溃的情况下丢失数据,因为他们甚至不会看到它)。

剩下的,你说你做了一些研究,所以你毫无疑问知道您不能为此使用 std::ofstream(也不能使用 FILE*);您必须在系统级别进行实际写入,然后打开具有特殊属性的文件,以确保完整同步。否则,操作可能会停留在操作系统缓冲了一会儿。据我所知,没有办法确保 rename 的这种同步。(但我不确定是否有必要,如果你总是保留两个版本:在这种情况下,我通常的惯例是写信给一个文件 "example.dat.new",然后当我写完后,删除任何名为 "example.dat.bak" 的文件,将 "example.dat" 重命名为"example.dat.bak",然后将"example.dat.new"重命名为“example.dat”。鉴于此,您应该能够弄清楚发生了什么或没有发生什么,并找到正确的文件(交互地,如果需要的话,或者插入一个初始行时间戳)。

关于c++ - 覆盖文件而不会有损坏文件的风险,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17884153/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com