Предотвращение создания пустого файла std::ifstream

#c #c 11 #file-io #fstream #iostream

#c #c 11 #file-io #fstream #iostream

Вопрос:

Следующий код создаст пустой файл, если файл с указанным путем не найден:

 std::ifstream file;
file.open(path, std::ios::in | std::ios::binary | std::ios::app);
//file.open(path, std::ios::in | std::ios::binary); will set fail() to true

if (!file.is_open())
    throw std::runtime_error("File could not be opened."); //never reached

file.seekg(0, file.end);
size_t size = file.tellg();
file.seekg(0, file.beg);

char* buffer = new char[size];
file.read(buffer, size);
file.close();

if (file.fail()) 
    throw std::runtime_error("Error reading file."); //why with only std::ios::in | std::ios::binary?
 

Есть ли способ избежать такого поведения ifstream ? Мне нужно, чтобы операция завершилась неудачно, если файл не найден, но она всегда выполняется успешно. Должен ли я вернуться fopen к такому поведению?

Комментарии:

1. Если вы откроете его в режиме чтения, это должно делать то, что вы хотите

Ответ №1:

Эта std::basic_filebuf::open ссылка содержит удобную таблицу, что происходит с различными флагами. И, как вы можете видеть, каждый раз app , когда используется поведение, заключается в создании нового файла, если он не существует.

Есть способ обойти это: открыть без использования app флага. Таким образом, открытие завершится ошибкой, которую вы можете затем проверить. Если это не приведет к сбою, вы закрываете файл и снова открываете с app помощью .

Комментарии:

1. Спасибо! app есть ли это, потому что в противном случае я получаю fail состояние после чтения всего файла, если я только передаю in | binary его. Любопытно, что с in | out | binary уходом fail state исчезает. Есть какие-нибудь идеи, почему это происходит? Я опубликовал весь код целиком.

2. Флаг out делает несуществующий файл больше не проблемой, потому что он может просто создать его для вас.

3. @EnigmaticBacon ошибка связана с существующим файлом. Если я только устанавливаю in и binary флаги, файл открывается правильно, и сообщаемый размер правильный, но fail() возвращается true . Этого не произойдет ни с app установленным, ни out с установленным флагом. Почему?

4. @InBetween Ну, конечно, вы получаете «сбой» после чтения всего файла при открытии в режиме только для чтения. В этом-то и дело. 🙂

5. Чтение данных, которых там нет, естественно, завершится неудачей. Это особенность. 🙂