我需要手动关闭ifstream吗?

时间:2009-04-14 14:59:26

标签: c++ ifstream raii

使用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 个答案:

答案 0 :(得分:227)

这就是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()

答案 1 :(得分:61)

您需要关闭文件吗?
NO

你应该关闭文件吗?
取决于。

如果文件无法正确关闭,您是否关心可能出现的错误情况?请记住,如果失败,请致电setstate(failbit)。由于 RAII ,析构函数会自动为您调用close(),但由于对象不再存在,因此不会为您提供测试失败位的方法。

答案 2 :(得分:11)

我同意@Martin。如果您写入文件,数据可能仍然位于缓冲区上,并且在调用close()之前可能无法写入文件。如果不手动操作,您不知道是否存在错误。不向用户报告错误是一种非常糟糕的做法。

答案 3 :(得分:6)

不,这是由ifstream析构函数自动完成的。您应该手动调用它的唯一原因是因为fstream实例具有较大的范围,例如,如果它是长生命类实例的成员变量。

答案 4 :(得分:4)

您可以允许析构函数完成它的工作。但就像任何RAII对象一样,有时候手动调用可以产生影响。例如:

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

没有按&#39;吨。这些过程突然退出的情况很少见。崩溃过程可以做类似的事情。