Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RAII with a filestream

Tags:

c++

raii

fstream

In the c++ language, there are multiple ways how to open and operate on a file. However the RAII-approach is very popular, since the destruktor takes care about freeing memory.

But what about the closing of a filestream? As far as i know, the destruktor should close the file anyway. However the destruktor also isn't allowed to throw any exceptions. So if i don't close my stream and it gets destructed at the end of a block i might loose information about the error, which might occur while closing.

Is my thinking correct? Despite of the RAII approach i should always close my streams?

Example:

{
  std::ofstream ofs;
  ofs.open ("test.txt");

  ofs << "blablabla";

  //do i need the following?
  ofs.close();
}
like image 374
hr0m Avatar asked Mar 13 '23 03:03

hr0m


2 Answers

The answer depens on whether you want to react on an error while closing, or not.

If you want to react, you have to close manually and check for error conditions (failing to close will set failbit):

std::ofstream str;
// Do something
str.close();
if (str.fail()) {
   // react on error
}

If you don't want to react, why bother? Just let the destructor close the file

like image 150
king_nak Avatar answered Mar 24 '23 16:03

king_nak


You should let the fstream destructor close the file.

As you said, the destructor won't throw, so you'd never see any error that occurred while closing the file, but the std::basic_fstream::close() member function has a void return type, so that can't signal an error either. Don't worry about this; just allow the destructor to close the file as for any other RAII class.


Note, the buffer that underlies the fstream has a close() member function too. This function returns NULL if there was an error, or the this pointer on success. This function is called from the destructor of the basic_filebuf, which in turn is called from the destructor of the basic_fstream. You shouldn't call this directly under normal use.

like image 38
Andrew Avatar answered Mar 24 '23 17:03

Andrew