Нужно ли вручную закрывать ifstream?
мне нужно вручную позвонить close()
когда я использую std::ifstream
?
например, в коде:
std::string readContentsOfFile(std::string fileName) {
std::ifstream file(fileName.c_str());
if (file.good()) {
std::stringstream buffer;
buffer << file.rdbuf();
file.close();
return buffer.str();
}
throw std::runtime_exception("file not found");
}
нужно позвонить file.close()
вручную? Не должно ifstream
использовать RAII для закрытия файлов?
5 ответов:
нет
это то, для чего RAII, пусть деструктор делает свою работу. Нет никакого вреда в закрытии его вручную, но это не способ C++, это программирование на C с классами.
если вы хотите закрыть файл до конца функции, вы всегда сможете воспользоваться вложенной области.
в стандарте (27.8.1.5 шаблон класса basic_ifstream),
ifstream
должно быть реализовано с помощьюbasic_filebuf
элемент, содержащий фактический дескриптор файла. Он проводится в качестве члена так, что когда объект ifstream разрушается, он также вызывает деструктор наbasic_filebuf
. И из стандарта (27.8.1.2), что деструктор закрывает файл:
virtual ˜basic_filebuf();
эффекты: уничтожает объект класса
basic_filebuf<charT,traits>
. Звонитclose()
.
вам нужно закрыть файл?
Нетвы должны закрыть файл?
Зависит.вы заботитесь о возможных условиях ошибки, которые могут возникнуть, если файл не закрывается правильно? Помните, что закрыть вызовы setstate (failbit), если это не удается. Деструктор вызовет close () для вас автоматически из-за RAII но не оставит вам способ тестирования бита сбоя, поскольку объект больше не существует.
Я согласен с @Martin. Если вы пишете в файл, данные могут все еще находиться в буфере и не могут быть записаны в файл до
close()
называется. Не делая этого вручную, вы понятия не имеете, была ли ошибка или нет. Не сообщать об ошибках пользователю-это очень плохая практика.
нет, это делается автоматически деструктором ifstream. Единственная причина, по которой вы должны вызвать его вручную, заключается в том, что экземпляр fstream имеет большую область видимости, например, если это переменная-член экземпляра класса long living.
вы можете позволить деструктору делать свою работу. Но, как и любой объект RAII, могут быть времена, когда вызов close вручную может иметь значение. Например:
#include <fstream> using std::ofstream; int main() { ofstream ofs("hello.txt"); ofs << "Hello world\n"; return 0; }
пишет содержимое файла. Но:
#include <stdlib.h> #include <fstream> using std::ofstream; int main() { ofstream ofs("hello.txt"); ofs << "Hello world\n"; exit(0); }