Search code examples
c++windowsfilefile-iobinaryfiles

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


My computer recently got shut down abruptly. When I powered it back on, I found out that some of the binary files I had written when the computer was running last time got corrupted. I investigated this, found that this is because data written using fwrite is not guaranteed to be written to disk immediately. I was told that in order to save my data without the risk of losing it in case of another abrupt power outage, I should make use of fsync function. But it looks like it is Unix/Linux only facility located in unistd.h. I am on Windows, how do I do the equivalent of fsync on Windows?

I want to protect data written using a simple program as follows -

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. Why I don't have a UPS is a long and an uninteresting story.Also, I am on Windows 8.1 and using Visual Studio 2013. Also, the files that were affected due to the abrupt power outage contained 0s. Some of them were full of 0s and some of them were only partially full of 0s. I did not write 0s to the file, so this was definitely a consequence of the power outage


Solution

  • For those who stop reading after the first paragraph, there are three steps following.

    1. Call fflush(fp). This will flush all of the data out of the C stdio buffers and into the operating system buffers.

    2. Use How do I get the file HANDLE from the fopen FILE structure?

    3. Then call FlushFileBuffers on the HANDLE. This will flush all of the data out of the Windows OS buffers and onto the disk.