234

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

4

5 回答 5

284

这就是 RAII 的用途,让析构函数完成它的工作。手动关闭它并没有什么坏处,但这不是 C++ 的方式,它是在 C 中使用类进行编程。

如果你想在函数结束之前关闭文件,你总是可以使用嵌套范围。

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

virtual ˜basic_filebuf();

效果:销毁类的对象basic_filebuf<charT,traits>。来电close()

于 2009-04-14T15:09:35.060 回答
78

需要关闭文件吗?

你应该关闭文件吗?
依靠。

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

于 2009-04-14T15:44:45.477 回答
16

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

于 2011-07-14T20:45:00.663 回答
6

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

没有。这些是进程突然退出的罕见情况。崩溃的过程也可以做类似的事情。

于 2018-05-22T11:37:39.727 回答
5

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

于 2009-04-15T09:24:43.820 回答