У меня есть код, который использует std::ifstream
читать из файла, но не использует какие-либо функции форматирования, предоставляемые std::ifstream
, По сути, он делает что-то вроде этого:
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();
}
Так как я непосредственно обрабатываю необработанные байты из файла, кажется, что лучше использовать std::filebuf
вместо 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();
}
На первый взгляд может показаться, что эти два фрагмента кода достигают одного и того же результата. Тем не менее, после проверки ссылки C ++, std::basic_istream::read()
говорит это:
Если внутренняя операция выдает исключение, оно перехватывается и устанавливается бадбит. Если для badbit задано исключение (), исключение перебрасывается.
поскольку badbit
используется, чтобы сигнализировать, что основной файл по какой-то причине поврежден (возможно, ОС больше не может получить доступ к файлу), похоже, что std::ifstream
фрагмент кода обработает эту возможность, вырвавшись из цикла (good()
вернусь false
).
Тем не мение, std::basic_streambuf::sgetn()
ничего не говорит о том, что основной файл становится недоступным. В нем также не упоминается возможность создания каких-либо исключений (но это не помечено как noexcept
).
Есть ли способ, при использовании std::filebuf
, правильно ли обрабатывать случай, когда файл преждевременно недоступен (т.е. еще не EOF)? (Или, возможно, мое понимание файлового ввода-вывода неверно?)
std::filebuf
Похоже, не имеет никакой формы обработки ошибок / отчетности вообще. Это просто жалко. Я имею в виду, почему бы и нет?
Таким образом, чтобы использовать его, единственным вариантом будет вернуться к старому доброму errno
и с момента входа в cppreference не говоря уже об этом, я полагаю, что вы не можете на это положиться (хотя я уверен, что на практике это работает).
Так, std::ifstream
Должен быть путь, если вы можете проложить свой путь через этого мамонта и несколько неясный список того, какой бит исключения делает что. И, конечно, если вы поступите таким образом, вы сможете контролировать, генерируются ли исключения или нет.
Опять же, нет никакого очевидного способа получить какой-либо код ошибки, когда что-то идет не так, и снова, если вы хотите попытаться представить какое-либо значимое сообщение об ошибке вашему пользователю (или, возможно, для технической поддержки), затем errno
это единственная игра в городе.
Все это приведет к распространению сообщений об ошибках «Что-то пошло не так». ЮК.
Других решений пока нет …