在不存在文件损坏风险的情况下覆盖文件
Overwriting a file without the risk of a corrupt file
我的应用程序经常希望保存文件以便以后再次加载。由于最近遭遇了一次崩溃,我想以这样一种方式编写操作,即保证我既有新数据,也有原始数据,但不会出现损坏的混乱。
我的第一个想法是按照以下行做一些事情(保存一个名为example.dat的文件):
- 为目标目录提供一个唯一的文件名,例如example.dat.tmp
- 创建那个文件并将我的数据写入其中
- 删除原始文件(例如.dat)
- 将临时文件重命名("移动")到原始文件所在的位置(example.dat.tmp->example.dat)
然后在加载时,应用程序可以遵循以下规则:
- 如果没有"example.dat"answers"example.dat.tmp",则首先运行/new项目,因此在默认值中加载/create new文件
- 如果"example.dat"而没有"example.dat.tmp",则加载example.dat(正常加载情况)
- 如果存在"example.dat.tmp",则为用户提供可能恢复数据的机会。如果"example.dat"也存在,请不要在没有显式用户常量的情况下覆盖它
然而,在做了一点研究后,我发现,除了我可以用文件刷新方法覆盖的操作系统缓存外,一些磁盘驱动器仍然在内部缓存,甚至可能对操作系统撒谎说它们已经完成了,所以4。可以完成,写入实际上并没有写入,如果系统出现故障,我就丢失了数据。。。
我不确定磁盘问题是否真的可以通过应用程序解决,但上面的一般规则是正确的吗?我是否应该保留文件的旧恢复副本更长的时间来确定,关于这些事情的指导方针是什么(例如,可接受的磁盘使用,用户应该选择,将这些文件放在哪里,等等)
此外,我应该如何避免用户和其他程序之间的潜在冲突,例如"example.dat.tmp"。我记得有时在其他软件中看到过"~example.dat",这是更好的约定吗?
如果磁盘驱动器向操作系统报告数据物理地在磁盘上,而不是,那么你就没有多少可以。很多磁盘确实缓存了一定数量的写入,并报告它们已完成,但这样的磁盘应该电池备份,并完成物理写入(在系统崩溃的情况下,他们不会丢失数据,因为甚至看不到)。
剩下的,你说你已经做了一些研究,所以你毫无疑问要知道,不能使用std::ofstream
(也不能使用FILE*
);您必须在系统级别进行实际写入,然后打开具有特殊属性的文件,以确保完整同步。否则,操作可能会在OS缓冲一段时间。据我所知,没有办法确保CCD_ 3的这种同步。(但我不确定是否有必要,如果你总是留两个版本:在这种情况下,我通常会写信给一个文件"example.dat.new"
,然后当我写完后,删除任何名为"example.dat.bak"
的文件,将"example.dat"
重命名为"example.dat.bak"
,然后将"example.dat.new"
重命名为"example.dat"
。考虑到这一点,你应该能够弄清楚发生了什么或没有发生什么,并找到正确的文件(如果需要的话,以交互方式插入,或者插入一个带有时间戳)。
如果不同的进程可能通过您所描述的相同协议,则在编写替代文件时应锁定实际的数据文件。
您可以使用flock
进行文件锁定。
至于临时文件名,您可以将进程ID作为其中的一部分,例如"example.dat.3124",没有其他同时运行的进程会生成相同的名称。
- 为什么在某些情况下不写入此文件?
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 有没有办法在不使用 getline() 的情况下从.csv文件中读取?
- 是否可以在没有真实文件的情况下创建 ifstream
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- 如何在添加文件的情况下在VSCode中调试C++程序
- 每个文件(理想情况下是每个部分)的 clang 格式样式覆盖
- 如何在不重新创建现有文件的情况下写入.txt文件
- 如何在不知道大小的情况下读取文本文件并存储到数组中
- 如何使用Winforms C#或C++.Net在不更改文件中其他内容的情况下修改jpg文件中的Orientation e
- 如何在不循环的情况下使用getline读取文件
- 在不打开应用程序的情况下在MinGW c++中播放声音(.wav)文件
- C++-在没有自定义.lib文件的情况下从Lua C模块调用Lua函数
- 如何在不使用文件扩展名的情况下使用命令行参数打开C++中的文本文件?
- 如何在不受其他文件影响的情况下"by itself" Visual Studio 项目中运行C++文件?
- 如何在不包含完整的文件系统头的情况下使用文件系统的类路径C++17?
- 如何在不设置 ulimit -n 的情况下解决套接字程序打开太多文件的错误
- Nlohmann 在不知道密钥的情况下解析 JSON 文件
- C++:如何在不将命令传递给 shell 的情况下执行文件?