使用fsync()在C或c++中保存二进制文件

Using fsync() for saving binary files in C or C++

本文关键字:c++ 保存 二进制文件 fsync 使用      更新时间:2023-10-16

我的电脑最近突然关机了。当我重新开机时,我发现我上次在电脑运行时写的一些二进制文件被损坏了。我对此进行了研究,发现这是因为使用fwrite写入的数据不能保证立即写入磁盘。我被告知,为了保存我的数据而没有在另一次突然停电的情况下丢失数据的风险,我应该使用fsync功能。但它看起来像是位于unistd.h的Unix/Linux专用设施。我在Windows上,我如何在Windows上执行等同于fsync的操作?

我想保护使用如下简单程序写入的数据-

void WriteBinFile(float var1, float var2, float var3)
{
    FILE *fp;
    fopen_s(&fp, "filename.dat", "wb");
    fwrite((void*)&var1, sizeof(float), 1, fp);
    fwrite((void*)&var2, sizeof(float), 1, fp);
    fwrite((void*)&var3, sizeof(float), 1, fp);
    // fsync(fp) ??? No such function exists on Windows. Here I want a facility to write data to disk in non-volatile manner.
    fclose(fp);
}

注:为什么我没有UPS,这是一个又长又无趣的故事。此外,我使用的是Windows 8.1和Visual Studio 2013。此外,由于突然停电而受影响的文件包含0 s。其中一些充满了0 s,而另一些只部分充满了0 s。我没有将0 s写入文件,所以这肯定是停电的结果

对于读到第一段就停止阅读的人,下面有三个步骤。

  1. 呼叫fflush(fp)。这将把所有数据从C工作室缓冲区中刷新到操作系统缓冲区中。

  2. 使用我如何从fopen文件结构中获得文件句柄?

  3. 然后调用HANDLE上的FlushFileBuffers。这将把所有的数据从Windows操作系统缓冲区中刷新到磁盘上。

你要找的是FlushFileBuffers。在你的例子中,FlushFileBuffers(fileno(fd)) .

在Windows中另一个有用的习语是由close(dup(fd))给出的,或者在你的例子中是close(dup(fileno(fp)))。这将刷新目录条目,以便文件大小对于正在增长的文件是正确的。

我可能错了,但我相信fflush(fp);应该能做到这一点。