当我使用std::ifstream时,我需要手动调用close()吗?

例如,在代码中:

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来关闭文件吗?


NO

这就是RAII的作用,让析构函数完成它的工作。手动关闭它没有什么坏处,但这不是c++的方式,它是用C语言和类编程。

如果想在函数结束之前关闭文件,可以使用嵌套作用域。

在标准(27.8.1.5类模板basic_ifstream)中,ifstream将由一个持有实际文件句柄的basic_filebuf成员实现。它作为一个成员保存,这样当一个ifstream对象析构时,它也会调用basic_filebuf上的析构函数。在标准(27.8.1.2)中,析构函数关闭文件:

虚拟˜basic_filebuf (); 效果:销毁类basic_filebuf<charT,traits>的对象。调用close()。


你需要关闭文件吗? 没有

你应该关闭文件吗? 视情况而定。

如果文件不能正确关闭,您是否关心可能发生的错误条件?记住close在失败时调用setstate(failbit)。由于RAII,析构函数将自动为您调用close(),但由于对象不再存在,因此不会给您留下测试失败位的方法。


不,这是由ifstream析构函数自动完成的。您应该手动调用它的唯一原因是,fstream实例具有较大的作用域,例如,如果它是一个长期存在的类实例的成员变量。


你可以让析构函数完成它的工作。但就像任何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);
}

不喜欢。这是进程突然退出的罕见情况。崩溃进程也可以做类似的事情。