I have some code which uses std::ifstream
to read from a file, but doesn't use any of the formatting features provided by std::ifstream
. It essentially does something like this:
std::ifstream in;
in.open("example.txt", std::ios_base::in | std::ios_base::binary);
if (in.is_open()) {
while (in.good()) {
in.read(buffer, buffer_size);
auto num_bytes = in.gcount();
/* do stuff with the bytes */
}
in.close();
}
Since I'm directly processing the raw bytes from the file, it seems like a better fit to use std::filebuf
instead of std::ifstream
:
std::filebuf in;
if (in.open("example.txt", std::ios_base::in | std::ios_base::binary) != nullptr) {
while (true) {
auto num_bytes = in.sgetn(buffer, buffer_size);
/* do stuff with the bytes */
if (num_bytes < buffer_size) break;
}
in.close();
}
On the surface, it might look like these two code snippets achieve the same outcome. However, upon inspection of the C++ reference, std::basic_istream::read()
says this:
If an internal operation throws an exception, it is caught and badbit is set. If exceptions() is set for badbit, the exception is rethrown.
Since badbit
is used to signal that the underlying file is broken for some reason (maybe the OS can't access the file any more), it appears that the std::ifstream
code snippet would handle this possibility by breaking out of the loop (good()
will return false
).
However, std::basic_streambuf::sgetn()
doesn't say anything about the possibility that the underlying file becomes inaccessible. It also does not mention the possiblity of any exceptions being thrown (but it is not marked as noexcept
).
Is there a way, when using std::filebuf
, to correctly handle the case when the file is prematurely inaccessible (i.e. not yet EOF)? (Or perhaps, my understanding of file I/O is wrong?)