Do I need to manually close an ifstream?

C++IfstreamRaii

C++ Problem Overview


Do I need to manually call close() when I use a std::ifstream?

For example, in the 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");
}

Do I need to call file.close() manually? Shouldn't ifstream make use of RAII for closing files?

C++ Solutions


Solution 1 - C++

NO

This is what RAII is for, let the destructor do its job. There is no harm in closing it manually, but it's not the C++ way, it's programming in C with classes.

If you want to close the file before the end of a function you can always use a nested scope.

In the standard (27.8.1.5 Class template basic_ifstream), ifstream is to be implemented with a basic_filebuf member holding the actual file handle. It is held as a member so that when an ifstream object destructs, it also calls the destructor on basic_filebuf. And from the standard (27.8.1.2), that destructor closes the file:

> virtual ˜basic_filebuf(); > > Effects: Destroys an object of class basic_filebuf<charT,traits>. Calls close().

Solution 2 - C++

Do you need to close the file?
NO

Should you close the file?
Depends.

Do you care about the possible error conditions that could occur if the file fails to close correctly? Remember that close calls setstate(failbit) if it fails. The destructor will call close() for you automatically because of RAII but will not leave you a way of testing the fail bit as the object no longer exists.

Solution 3 - C++

I agree with @Martin. If you write to the file, the data may still be sitting on a buffer and may not get written to the file until close() is called. Without doing it manually, you have no idea whether there was an error or not. Not reporting errors to a user is a very bad practice.

Solution 4 - C++

You can allow the destructor to do it's job. But just like any RAII object there may be times that calling close manually can make a difference. For example:

#include <fstream>

using std::ofstream;

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

writes file contents. But:

#include <stdlib.h>

#include <fstream>

using std::ofstream;

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

doesn't. These are rare cases where a process suddenly exits. A crashing process could do similar.

Solution 5 - C++

No, this is done automatically by the ifstream destructor. The only reason you should call it manually, is because the fstream instance has a big scope, for example if it is a member variable of a long living class instance.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEdison Gustavo MuenzView Question on Stackoverflow
Solution 1 - C++EclipseView Answer on Stackoverflow
Solution 2 - C++Martin YorkView Answer on Stackoverflow
Solution 3 - C++Mark EdwardsView Answer on Stackoverflow
Solution 4 - C++ericcurtinView Answer on Stackoverflow
Solution 5 - C++Dimitri C.View Answer on Stackoverflow