typedef struct {
char c[20];
int i;
} header;
void foo(std::string s) {
std::ifstream ifs(s.c_str(), std::ios_base::binary | std::ios_base::in);
if (ifs) {
what is the point of filebuf ?
None, here.
I can't see why you're using it.
Until you do more complex operations, filebuf
is an implementation detail†.
† (Sort of.)
First, the real point of filebuf
is that it derives from
streambuf
, and that an istream
whose streambuf is a filebuf
will behave largely like an ifstream
. This is important; the
>>
operator aren't virtual, and since many of them aren't
members, they cannot be virtual. All input must pass through
the istream
, not the ifstream
that's derived from it. More
generally, the ifstream
can be thought of as just
a convenience class; it's constructor provides the istream
base class with a filebuf
, its destructor destructs the
filebuf
, and it provides access to the functionality of
filebuf
which isn't present in the base streambuf
.
That doesn't mean that you cannot use the streambuf
directly,
you can, and there are cases where it is appropriate. But if
you do, you have to take care of the error handling. When you
call istream::read
asking for a certain number of bytes, and
those bytes aren't there, istream::read
will note the end of
file, set the necessary error bits, and provide the count of
what was actually read through istream::gcount
. If you're
reading byte by byte, and don't know how many bytes there might
be, then all of that may not mean much (but you'll probably want
to set eofbit
if you see EOF). If you're trying to read
a specific number of bytes (say a four byte integer), then
istream:read
will set the appropriate error bits if you cannot
read four bytes, so you can easily test for the error.
EDIT
One additional comment: you should probably put the reading of
the file in a separate process, which takes an std::istream&
.
You really don't want the reading code to know that it is
dealing with an ifstream
, rather than some other sort of
stream. (Also: there's no need to seek if you've just opened
the file.)
Just use basic_istream<>::read() to read raw, unformatted byte data:
void foo(std::string s) {
std::ifstream ifs(s.c_str(), std::ios_base::binary | std::ios_base::in);
if (ifs) {
char buffer[20];
if (!ifs.read(buffer, 20)) {
// Handle error
}
}
}
there is a
read
forifstream
Yes, and that's what you use to read unformatted data from the stream; hence the name.
if I'm supposed to use that method, what is the point of
filebuf
?
It's used by the stream to handle low-level file access and buffering. You can access it if you need to mess around with those details, but usually there's no need to. You certainly wouldn't mess around with it if you just want to read from the stream.