Dois-je fermer manuellement un ifstream?
dois-je appeler manuellement close()
quand j'utilise un std::ifstream
?
par exemple, dans le code:
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");
}
Dois-je appeler file.close()
manuellement? ifstream
ne devrait-il pas utiliser RAII pour fermer des fichiers?
5 réponses
Non
C'est à ça que sert RAII, laissez le destructeur faire son travail. Il n'y a pas de mal à le fermer manuellement, mais ce n'est pas la façon C++, c'est la programmation en C avec des classes.
Si vous voulez fermer le fichier avant la fin d'une fonction, vous pouvez toujours utiliser un imbriquée portée.
dans la norme (27.8.1.5 Class template basic_ifstream), ifstream
doit être implémenté avec un membre basic_filebuf
détenant le fichier réel gérer. Il est tenu comme un membre de sorte que lorsqu'un objet ifstream se détruit, il appelle également le destructeur sur basic_filebuf
. Et de la norme (27.8.1.2), ce destructeur ferme le fichier:
virtual ˜basic_filebuf();
effets: détruit un objet de la classe
basic_filebuf<charT,traits>
. Appelleclose()
.
avez-vous besoin de fermer le fichier?
N ° 151930920"
devez-vous fermer le dossier?
Dépend.
vous souciez-vous des éventuelles conditions d'erreur qui pourraient se produire si le fichier ne se ferme pas correctement? Rappelez-vous que les appels fermés setstate(failbit) si elle échoue. Le destructeur appellera close () pour vous automatiquement en raison de RAII mais ne vous laissera pas une façon de tester l'échec peu que l'objet n'existe plus.
je suis d'accord avec @Martin. Si vous écrivez au fichier, les données peuvent toujours être assises sur un tampon et ne peuvent pas être écrites au fichier jusqu'à ce que close()
soit appelé. Sans le faire manuellement, vous n'avez aucune idée s'il y a une erreur ou pas. Ne pas signaler des erreurs à un utilisateur est une très mauvaise pratique.
Non, Ceci est fait automatiquement par le destructeur ifstream. La seule raison pour laquelle vous devriez l'appeler manuellement, c'est parce que les fstream exemple, a une grande portée, par exemple si c'est une variable membre d'une longue vie instance de classe.
vous pouvez laisser le destructeur faire son travail. Mais tout comme n'importe quel objet RAII, il peut y avoir des moments où le fait d'appeler à la main peut faire une différence. Par exemple:
#include <fstream>
using std::ofstream;
int main() {
ofstream ofs("hello.txt");
ofs << "Hello world\n";
return 0;
}
, écrit le contenu du fichier. Mais:
#include <stdlib.h>
#include <fstream>
using std::ofstream;
int main() {
ofstream ofs("hello.txt");
ofs << "Hello world\n";
exit(0);
}
Pas . Il s'agit de rares cas où un processus disparaît soudainement. Un processus de collision pourrait faire la même chose.