I was reading the cplusplus.com tutorial on I/O. At the end, it says fstream buffers are synchronized with the file on disc
Explicitly, with manipulators: When certain manipulators are used on
streams, an explicit synchronization takes place. These manipulators
are: flush and endl.
and
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.
in addition to a few other implicit cases ( such as destruction and stream.close() )
What is the difference between calling fstream::flush() and fstream::sync()? endl?
In my code, I've always used flush().
Documentation on std::flush():
Flush stream buffer
Synchronizes the buffer associated with the stream
to its controlled output sequence. This effectively means that all
unwritten characters in the buffer are written to its controlled
output sequence as soon as possible ("flushed").
Documentation on std::streambuf::sync():
Synchronize input buffer with source of characters
It is called to synchronize the stream buffer with the controlled sequence (like the file in the case of file streams). The public member function pubsync calls this protected member function to perform this action.
Forgive me if this is a newbie question; I am a noob.
basic_ostream::flush
This is a non-virtual function which writes uncommited changes to the underlying buffer. In case of error, it sets an error flag in the used stream object. This is because the return value is a reference to the stream itself, to allow chaining.
basic_filebuf::sync
This is a virtual function which writes all pending changes to the underlying file and returns an error code to signal success or failure.
endl
This, when applied to an ostream
, writes an '\n'
to the stream and then calls flush
on that stream.
So, essentially: flush
is a more general function for any stream, whereas sync
is explicitly bound to a file. flush
is non-virtual, whereas sync
is virtual. This changes how they can be used via pointers (to base class) in the case of inheritance. Furthermore, they differ in how they report errors.
sync
is a member of input
streams, all unread characters are cleared from the buffer. flush
is a member of output
streams and buffered output is passed down to the kernel.
C++ I/O involves a cooperation between a number of classes: stream, buffer, locale and locale::facet-s.
In particular sync
and flush
are member function that exist in both stream
and streambuf
, so beware to what documentation you are referring, since they do different things.
On streams flush
tells the stream to tell the buffer (note the redirection) to flush its content onto the destination. This makes sure that no "pending write" remains.
std::endl
, when applied to thestream
with <<
, is no more than a
thestream.put('\n'); thestream.flush();
Always on streams, sync
tells the stream to tell the buffer to flush the content (for output) and read (for input) as much as it can to refill the buffer.
Note that -in buffers- sync can be also called internally by overflow
to handle the "buffer full" (for output) and "buffer empty" (for input) situations.
I thus sense, sync
is much more an "internal" function used in stream to buffer communication and buffer implementation (where it is virtual and overridden in different buffer types), while flush
is much more an interface between the stream and the client program.
endl
... is just a shortcut.
I've understood it to be as follows:
flush
will get the data out of the library buffers into the OS's write buffers and will eventually result in a full synchronization (the data is fully written out), but it's definitely up to the OS when the synch will be complete.
synch
will, to the extent possible in a given OS, attempt to force full synchronization to come about--but the OS involved may or may not facilitate this.
So flush
is: get the data out of the buffer and in line to be written.
synch
is: if possible, force the data to be definitively written out, now.
That's been my understanding of this, but as I think about it, I can't remember how I came to this understanding, so I'm curious to hear from others, too.