c – 覆盖文件而不存在文件损坏的风险

因此,我的应用程序通常希望保存文件以便以后再次加载.最近因崩溃而不幸,我想以这样的方式编写操作,以确保我拥有新数据或原始数据,但没有损坏的混乱.

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

>为目标目录提供唯一的文件名,例如: example.dat.tmp
>创建该文件并将数据写入其中.
>删除原始文件(example.dat)
>将临时文件重命名(“移动”)到原始文件的位置(example.dat.tmp – > example.dat).

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

>如果没有“example.dat”而没有“example.dat.tmp”,首先运行/ new project,所以加载defaults / create new文件.
>如果“example.dat”而没有“example.dat.tmp”,则加载example.dat(正常载荷情况)
>如果“example.dat.tmp”存在,则为用户提供可能恢复数据的机会.如果“example.dat”也存在,请不要在没有显式用户常量的情况下覆盖它.

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

我不确定磁盘问题是否可以由应用程序解决,但是一般规则是否正确?我是否应该保留文件的旧恢复副本以确保更长时间,有关此类事项的准则是什么(例如,可接受的磁盘使用情况,用户应该选择,放置此类文件的位置等).

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

最佳答案 如果磁盘驱动器向操作系统报告该数据

物理上在磁盘上,但事实并非如此,那么你就不多了

可以做到这一点.很多磁盘都会缓存一定数量的磁盘

写,并报告他们完成,但这样的磁盘应该有

电池备份,无论如何都完成物理写入

(并且在系统崩溃的情况下,他们不会丢失数据,因为他们

甚至都不会看到它.

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

点赞