Re: is std::ifstream buffered or not?
Maxim Yegorushkin wrote:
kanze wrote:
[]
I understand std::cout and std::cin are buffered, and it
makes sense that they are. However, I do not see why
std::ifstream and std::ofstream would be buffered because
the filesystem and even the harddrive does some buffering.
Wouldn't that be meaningless?
No. System requests are (or were) expensive. In fact, I
would generally say that the reverse is true: cout and cin
are often connected to interactive devices, where you don't
want buffering; ifstream and ofstream rarely are.
Then again, this could depend on the implementation. I'm
not familiar enough with the C++ STL specification.
There is a function in streambuf: setbuf, which can be used
to set a user defined buffer. But an implementation is only
required to respect it if it is used to request unbuffered
IO (which means in practice a buffer size of 1).
Is it true that there is no way to make std::streambuf
unbuffered? The standard requires underflow() to either fill
the pending sequence or return EOF, which means that the
pending sequence (buffer) has to be present. IOW,
std::streambuf input buffer has to be at least one character
long.
The function underflow() does not extract anything from the
stream; a later call to streambuf::sgetc() must return exactly
the same character as underflow() returned. Or in the terms of
the standard (concerning underflow): "Returns:
traits::to_int_type(c), where c is the first character of the
pending sequence, without moving the input sequence position
past it."
In the classical iostreams, it stopped there. There must be at
least a one character buffer. The standard iostreams modified
this somewhat, in that it requires a "pending sequence", which
is not necessarily in the buffer, and provides a second
function, streambuf::uflow(), which has the same semantics as
underflow(), but will remove the character from the pending
sequence (where ever the pending sequence may be). On the other
hand, it requires a backup sequence somewhere, so that putback
can work. I think that the intent is for sgetc() to call
underflow(), and for sbumpc() to call uflow(). (I'm not really
too familiar with these aspects. I learned iostreams on the
classical iostreams, and while Dietmar K?hl once pointed out to
me the existance of uflow(), and suggested that it could be used
to implement input without a buffer, I've not looked at the
issues in detail.)
Practically speaking: it's generally simpler, and sometimes
necessary, to use a buffer in the streambuf, if only to support
"peeking" (non-extracting reads) and putback. And if you're
using an in memory buffer, it's just a lot simpler to let the
base class streambuf handle its management, by setting it up
with gptr.
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]