views:

140

answers:

1

I'm saving a file on an USB drive and need to make sure that it's completely written to avoid corruption in case the USB drive is not removed properly. Well I've done some research and it seems this is possible via calling the FlushFileBuffers Win32 function. But the problem is, I'm saving using boost::serialization and thus don't have access to the actual file HANDLE. I wonder what is the proper way to flush the file? Thanks!

+2  A: 

Call ostream::flush on the output stream you created your archive object with:

// create and open a character archive for output
std::ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs);

...

ofs.flush();

You could also just let the objects go out of scope which should flush everything:

{
    // create and open a character archive for output
    std::ofstream ofs("filename");
    boost::archive::text_oarchive oa(ofs);

    // going out of scope flushes the data
}

Note, you still need to properly unmount your USB device. Flushing the data just makes sure it gets from userland into the kernel, but the kernel can also do it's own buffering.

R Samuel Klatchko
Thanks for the answer! Is there any way to guarantee file saving even if the drive is not unmounted properly, like temporarily switching off write caching on the volume?
Alex Jenter
@Alex - unfortunately, I don't know how to do that in Windows (or if it's even possible). I'd recommend asking that as new question.
R Samuel Klatchko
@Alex: No. It's a FAT problem fundamentally. You need a transactional file system for that, like Ext3/exFAT. You can of course improve odds. E.g. call `FlushFileBuffers` on the volume handle, and call the `CreateFile` function with the `FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH` flags.
MSalters
@MSalters: Thanks!
Alex Jenter