检查文件内容是否已实际写入磁盘 - 未在磁盘控制器的缓冲区中排队
Check if file content has been actually written to disk - not being queued in disk controller's buffer
我编写了一个程序,将两个小文件压缩成一个更大的文件。我首先从输入文件中读取数据,合并数据,然后将输出写入临时文件。完成后,我将临时文件重命名为所需的文件名(位于磁盘上的同一分区中)。下面是伪代码:
FILE* fp_1 = fopen("file_1.dat", "r+b");
FILE* fp_2 = fopen("file_2.dat", "r+b");
FILE* fp_out = fopen("file_tmp.dat", "w+b");
// 1. Read data for the key in two files
const char* data_1 = ...;
const char* data_2 = ...;
// 2. Merge data, store in an allocated buffer
// 3. Write merged buffer to temp file
fwrite(temp_buff, estimated_size, 1, fp_out);
fflush(fp_out);
fclose(fp_1);
fclose(fp_2);
fclose(fp_out);
// Now rename temp file to desired file name
if(std::rename("file_tmp.dat", "file_out.dat") == 0)
{
std::remove("file_1.dat");
std::remove("file_2.dat");
}
我用两个分别为5mb的输入文件反复测试了这个程序。有一次,我突然拔掉了电源线,关闭了系统。重新启动系统后,我检查了数据,发现输入文件被删除,file_out.dat
被全0填满。这让我相信,在删除2个输入文件后,系统就会崩溃,而输出数据仍然在磁盘控制器的缓冲区中的某个地方。如果这是真的,那么我是否有办法检查数据是否已经写入磁盘?
一般情况下不需要。即使你告诉操作系统等待数据写入(使用sync
API家族),一些磁盘对操作系统撒谎,声称写入完成,而实际上它只是在硬盘的板载RAM缓存中排队,这将在突然断电时丢失。
你能做的最好的就是明确地要求操作系统告诉磁盘"真的,真的同步所有东西,然后阻塞直到完成"。在执行了fflush
之后(它只告诉stdio库将所有用户模式缓冲的数据发送到操作系统,操作系统通常将其保存在内核缓冲区中,然后在后台将内核缓冲区同步到磁盘),要么使用fsync
限制范围,要么使用sync
或syncfs
(前者同步所有文件系统,后者将范围限制到对应于单个文件描述符的文件系统)。
为了最大限度的安全,您需要:
- 在最终的
fflush
之后但在rename
之前做一个目标fsync
(这样新文件在替换旧文件之前在磁盘上完成),和 - 在
rename
之后但在remove
调用之前做更广泛的sync
/syncfs
(因此在删除源文件之前,rename
的元数据更新已经完成)
如果您不介意在输入数据仍然存在的情况下损坏输出数据,则省略第1步是可以的。
当然,就像我说的,这是尽最大努力;如果磁盘控制器欺骗了操作系统,那么除了为磁盘编写新的固件和驱动程序之外,你什么也做不了,这可能太过分了。
相关文章:
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 对于四轴飞行器,PID中I控制器的理想值应该是多少
- 根据 GetLastError 直接写入磁盘会导致错误代码 5
- 如何集成 HID USB 控制器?
- 矢量和其他容器如何在磁盘上工作?
- 如何从整个磁盘中排除要装载的一个文件
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 更高效地在微控制器上对C++进行基准测试
- 如何将 IPropertyBag 保存到磁盘
- 防止临时对象文件访问 MSVC 中的磁盘
- 排队功能
- 如何修复 Arduino LED 串控制器的代码?
- 即使使用 FILE_FLAG_DELETE_ON_CLOSE 属性创建文件,文件也会保留在磁盘上
- Linux 源代码中普通磁盘文件的"轮询"功能在哪里实现?
- 如何在 Windows 中通过 SSL 端口枚举域控制器
- 文件删除(使用取消链接)与释放所有磁盘空间之间的延迟
- 如何使用 c++ 在命令行中创建一个简单的字符控制器?
- 在 Visual Studio 中调试时,是否可以将一些 C/C++ 结构内容保存到磁盘?
- 为什么玩家控制器"own"偏航俯仰和滚动,但角色"owns"它的位置?
- 检查文件内容是否已实际写入磁盘 - 未在磁盘控制器的缓冲区中排队