在 C 或 C++ 中使用 fsync() 保存二进制文件
Using fsync() for saving binary files in C or C++
我的电脑最近突然关机了。当我重新打开电源时,我发现我上次 运行 时写入的一些二进制文件已损坏。我调查了一下,发现这是因为使用 fwrite
写入的数据不能保证立即写入磁盘。有人告诉我,为了保存我的数据而不会在另一次突然断电的情况下丢失数据,我应该使用 fsync
函数。但它看起来像是 Unix/Linux only facility 位于 unistd.h
。我在 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);
}
P.S。为什么我没有 UPS 是一个漫长而无趣的 story.Also,我在 Windows 8.1 并使用 Visual Studio 2013。另外,由于突然电源而受到影响的文件中断包含 0
秒。其中一些充满了 0
,而另一些则只充满了部分 0
。我没有写0
s到文件,所以这肯定是停电的结果
我可能是错的,但我相信 fflush(fp);
应该可以解决问题。
对于读完第一段就停止阅读的人,还有 三 个步骤。
致电fflush(fp)
。这会将所有数据从 C stdio 缓冲区刷新到操作系统缓冲区。
使用How do I get the file HANDLE from the fopen FILE structure?
然后在 HANDLE 上调用 FlushFileBuffers
。这会将 Windows OS 缓冲区中的所有数据刷新到磁盘上。
您要找的是FlushFileBuffers
。在你的情况下,FlushFileBuffers(fileno(fd))
.
Windows 中的另一个有用习语由 close(dup(fd))
给出,或者在您的情况下 close(dup(fileno(fp)))
。这会刷新目录条目,以便文件大小对于不断增长的文件来说是正确的。否则目录仅在文件关闭时更新。
我的电脑最近突然关机了。当我重新打开电源时,我发现我上次 运行 时写入的一些二进制文件已损坏。我调查了一下,发现这是因为使用 fwrite
写入的数据不能保证立即写入磁盘。有人告诉我,为了保存我的数据而不会在另一次突然断电的情况下丢失数据,我应该使用 fsync
函数。但它看起来像是 Unix/Linux only facility 位于 unistd.h
。我在 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);
}
P.S。为什么我没有 UPS 是一个漫长而无趣的 story.Also,我在 Windows 8.1 并使用 Visual Studio 2013。另外,由于突然电源而受到影响的文件中断包含 0
秒。其中一些充满了 0
,而另一些则只充满了部分 0
。我没有写0
s到文件,所以这肯定是停电的结果
我可能是错的,但我相信 fflush(fp);
应该可以解决问题。
对于读完第一段就停止阅读的人,还有 三 个步骤。
致电
fflush(fp)
。这会将所有数据从 C stdio 缓冲区刷新到操作系统缓冲区。使用How do I get the file HANDLE from the fopen FILE structure?
然后在 HANDLE 上调用
FlushFileBuffers
。这会将 Windows OS 缓冲区中的所有数据刷新到磁盘上。
您要找的是FlushFileBuffers
。在你的情况下,FlushFileBuffers(fileno(fd))
.
Windows 中的另一个有用习语由 close(dup(fd))
给出,或者在您的情况下 close(dup(fileno(fp)))
。这会刷新目录条目,以便文件大小对于不断增长的文件来说是正确的。否则目录仅在文件关闭时更新。