The following looks sensible, but I've heard that the data could theoretically still be in a buffer rather than on the disk, even after the close() call.
#include <fstream>
int main()
{
ofstream fsi("test.txt");
fsi << "Hello World";
fsi.flush();
fsi.close();
return 0;
}
You cannot to this with standard tools and have to rely on OS facilities.
For POSIX fsync
should be what you need. As there is no way to a get C file descriptor from a standard stream you would have to resort to C streams in your whole application or just open the file for flushing do disk. Alternatively there is sync
but this flushes all buffers, which your users and other applications are going to hate.
You could guarantee the data from the buffer is written to disk by flushing the stream. That could be done by calling its flush()
member function, the flush
manipulator, the endl
manipulator.
However, there is no need to do so in your case since close
guarantees that any pending output sequence is written to the physical file.
§ 27.9.1.4 / 6:
basic_filebuf< charT, traits >* close();
Effects: If is_open() == false, returns a null pointer. If a put area exists, calls overflow(traits::eof()) to flush characters. (...)
§ 27.9.1.4
basic_filebuf* close();
Effects: If is_open() == false, returns a null pointer. If a put area
exists, calls overflow(traits::eof()) to flush characters. If the last
virtual member function called on *this (between underflow, overflow,
seekoff, and seekpos) was overflow then calls a_codecvt.unshift
(possibly several times) to determine a termination sequence, inserts
those characters and calls overflow(traits::eof()) again. Finally,
regardless of whether any of the preceding calls fails or throws an
exception, the function closes the file (as if by calling
std::fclose(file)). If any of the calls made by the function,
including std::fclose, fails, close fails by returning a null pointer.
If one of these calls throws an exception, the exception is caught and
rethrown after closing the file.
It's guaranteed to flush the file. However, note that the OS might keep it cached, and the OS might not flush it immmediately.
Which operating system are you using?
You need to use Direct (non-buffered) I/O to guarantee the data is written directly to the physical device without hitting the filesystem write-cache. Be aware it still has to pass thru the disk cache before getting physically written.
On Windows, you can use the FILE_FLAG_WRITE_THROUGH flag when opening the file.
The close()
member function closes the underlying OS file descriptor. At that point, the file should be on disk.
I'm pretty sure the whole point of calling close()
is to flush the buffer. This site agrees. Although depending on your file system and mount settings, just because you've 'written to the disk' doesn't mean that your file system drivers and disk hardware have actually taken the data and made magnet-y bits on the physical piece of metal. It could probably be in a disk buffer still.
How abt flushing before closing?