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?

157
demandé sur Jamal 2009-04-14 18:59:26

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> . Appelle close() .

208
répondu Eclipse 2011-05-04 14:14:14

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.

55
répondu Martin York 2012-02-14 19:58:05

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.

9
répondu Mark Edwards 2012-11-17 04:26:22

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.

4
répondu Dimitri C. 2011-04-29 13:26:58

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.

2
répondu ericcurtin 2018-05-22 11:37:39