How do I emulate fsync with ofstream?

Jan 29, 2009 at 11:20pm
I'm porting a program that used stdio file facilities to use std::ofstream instead. The original program uses fsync to force a file's buffers out to the disk. The fsync() is used because I'm writing a logging file, and want to ensure that data is written ASAP (i.e., before a crash). The log file is always open, until the program is terminated.

I cannot figure out how to force the flush to disk with ofstream. I've tried the flush() call, but that just flushes the program's buffers out into the file system's buffers, and does not guarantee that the data is physically written to disk. I also tried:

pMyStream->rdbuf()->pubsync();


but that didn't help either.

I can observe an LED that lights up when the write actually takes place, so that's how I know if it worked or not.

How do I emulate fsync() with an ofstream?

Thanks.
Jan 30, 2009 at 12:19am
Explicitly, with member function sync(): Calling stream's member function sync(), which takes no parameters, causes an immediate synchronization. This function returns an int value equal to -1 if the stream has no associated buffer or in case of failure. Otherwise (if the stream buffer was successfully synchronized) it returns 0.

http://www.cplusplus.com/doc/tutorial/files.html
Last edited on Jan 30, 2009 at 12:19am
Jan 30, 2009 at 12:42am
Maybe it's just me, but I cannot find a sync() function associated with an ofstream class. There is a private sync() function in its rdbuf(), and a public sync function that I pointed out in my original post. The files tutorial is kinda fuzzy on where that sync function can be found.

Anyway, I believe that the sync() function only synchronizes the program's buffers with the operating system's file system buffers. In other words, the buffers are guaranteed to be flushed into the disk cache where other programs can see them when making file system requests. But that's not an indication that the data has physically been written to disk yet.

I'm looking for a way to tell the OS to force the associated buffers from the file system disk cache out to the physical media. That's what fsync() does, which I've proven by closing a file with and without calling fsync. When I do call fsync(), I can see my LED blink immediately. When I don't call fsync(), I can see the LED blink 30 seconds later as the OS decides it is time to flush the disk cache out to the physical media.

That final step (flushing to physical media) is the problem I need to solve with an ofstream.

As a last resort, I suppose I can utilize fsync by reopening the file with fopen, calling fsync, then fclose. That might do it.
Jan 30, 2009 at 12:46am
Jan 30, 2009 at 9:57pm
Thanks for the link to the info on _commit. That's the equivalent of the GCC fsync command. My program has to run under Windows/Visual Studio and Linux/GCC, so I needed both solutions.

I found a suggestion elsewhere that I could first open a file using old-fashioned fopen, then use the FILE* pointer in a constructor to ofstream. That worked on Windows, but not under GCC/Linux.

I decided to stick with old-fashioned file I/O exclusively, and avoid the ofstream altogether. I was able to conditionally compile the call to either _commit() or fsync(), based on my target platform. I tested both, and they both worked, flushing the disk cache out to the physical disk immediately.

Thanks for the help. Consider this solved.
Topic archived. No new replies allowed.