Pergunta

Preciso close() chamada manualmente quando eu uso um std::ifstream?

Por exemplo, no código:

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");
}

Preciso chamada file.close() manualmente? Não deve ifstream fazer uso RAII para fechamento de arquivos?

Foi útil?

Solução

NO

Isto é o que RAII é para, deixe o destruidor fazer o seu trabalho. Não há mal nenhum em fechá-lo manualmente, mas não é o C ++ maneira, está programando em C com classes.

Se você quiser fechar o arquivo antes do fim de uma função você sempre pode usar um escopo aninhado.

No padrão (27.8.1.5 classe de modelo basic_ifstream), ifstream está a ser implementado com um membro basic_filebuf segurando a alça arquivo real. Ele é tido como um membro de modo que quando um objeto ifstream destrói, ele também chama o destruidor sobre basic_filebuf. E a partir do padrão (27.8.1.2), que destructor fecha o arquivo:

virtual ˜basic_filebuf();

Efeitos: Destrói um objeto de basic_filebuf<charT,traits> classe. Chamadas close().

Outras dicas

Você precisa fechar o arquivo?
NO

Se você fechar o arquivo?
Depende.

Você se importa com as possíveis condições de erro que podem ocorrer se o arquivo não se fecha corretamente? Lembre-se que triz setstate(failbit) se ele falhar. O destruidor vai chamar close() automaticamente para você por causa de RAII , mas não vai deixar você uma maneira de testar o bit falhar como o objeto não existe mais.

Concordo com @ Martin. Se você escrever para o arquivo, os dados ainda podem estar sentado em um buffer e não pode ficar gravada no arquivo até close() é chamado. Sem fazê-lo manualmente, você não tem idéia se houve um erro ou não. Não relatar erros para um usuário é uma prática muito ruim.

Não, isso é feito automaticamente pelo destruidor ifstream. A única razão que você deve chamá-lo manualmente, é porque a instância fstream tem um grande alcance, por exemplo, se é uma variável membro de uma instância de long classe vida.

Você pode permitir que o destruidor de fazê-lo do trabalho. Mas, como qualquer objeto RAII pode haver momentos em que chamar perto manualmente pode fazer a diferença. Por exemplo:

#include <fstream>

using std::ofstream;

int main() {
  ofstream ofs("hello.txt");
  ofs << "Hello world\n";
  return 0;
}

escreve o conteúdo do arquivo. Mas:

#include <stdlib.h>

#include <fstream>

using std::ofstream;

int main() {
  ofstream ofs("hello.txt");
  ofs << "Hello world\n";
  exit(0);
}

não. Estes são raros casos em que um processo de repente sai. Um processo de bater podia fazer semelhante.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top