do I need to close a std::fstream?
I think the previous answers are misleading.
fstream
is a proper RAII object, it does close automatically at the end of the scope, and there is absolutely no need whatsoever to call close
manually when closing at the end of the scope is sufficient.
In particular, it’s not a “best practice” and it’s not necessary to flush the output.
And while Drakosha is right that calling close
gives you the possibility to check the fail bit of the stream, nobody does that, anyway.
In an ideal world, one would simply call stream.exceptions(ios::failbit)
beforehand and handle the exception that is thrown in an fstream
’s destructor. But unfortunately exceptions in destructors are a broken concept in C++ so that’s not a good idea.
So if you want to check the success of closing a file, do it manually (but only then).
Do I need to manually close an ifstream?
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>
. Callsclose()
.
Is closing fstream ( I/O ) necessary?
A std::fstream
will close itself when it goes out of scope.
In your case however, the second call to std::fstream::open()
fails, which sets the failbit
on the stream (and could thrown an exception, but obviously doesn't in this case). With the failbit
set, additional attempts to write to that stream will fail. See Return Value section here: http://www.cplusplus.com/reference/fstream/ofstream/open/
Should I close a file when it wasn't able open?
No, that's not necessary to be done explicitly. (File) streams are closed when going out of scope implicitly always.
The close()
function of a std::iostream()
also is an idempotent operation, and never will harm the streams state beyond the stream gets closed (or never was successfully opened).
What happens if I never call `close` on an open file stream?
There is no difference. The file stream's destructor will close the file.
You can also rely on the constructor to open the file instead of calling open()
. Your code can be reduced to this:
#include <fstream>
int main()
{
std::ofstream myfile("example.txt");
myfile << "Writing this to a file.\n";
}
Closing files using fstream
Why doesn't the compiler recognize that you already closed the file?
These statements are syntactically correct, so the compiler won't complain.
Theoretically the second close()
call might fail at runtime, but since its an idempotent operation, it won't.
As you can see from the reference documentation:
Notes
This function is called by the destructor of basic_fstream when the stream object goes out of scope and is not usually invoked directly.
It must even be implemented idempotentially.
Does ofstream close its files automatically?
ofstream
will close files when its destructor is called, i.e. when it goes out of scope. However, calling close()
certainly doesn't do any harm and expresses your intentions to maintenance programmers.
Calling close()
also allows you to check if the close() was successful because you can then also check the failbit
:
http://www.cplusplus.com/reference/iostream/ofstream/close/
Will forgetting to call std::ofstream close function lead to memory leak?
When your std::ofstream
object goes out of scope it will automatically be closed due to the use of RAII
and the automatic calling of the object destructor.
In this situation your code is perfectly acceptable and would cause no memory leaks. There is no need to call close manually at all.
Only use close
if you wish to reuse the object before it goes out of scope i.e if the ofstream object was a member of a class and you wish to re-use it then its possible to call close
on it and then re-open it with a different file etc.
What does std::ofstream::close() actually do?
Other than flushing the userspace buffers, i.e. flush()
, close(2)
is called on the underlying file-descriptor. It depends on the operating system what happens then, but most likely nothing happens to the actual storage occupied by the file.
What will happen is that the (if the file descriptor was the last reference in that process to that file) file entry associated with the file gets removed from the open-file table of the process. I.e. freeing process-associated kernel-memory.
Explicitly saving the file using fstream without closing the file in C++
Files are often some stream of bytes, and could be much bigger than your virtual address space (e.g. you can have a terabyte sized file on a machine with only a few gigabytes of RAM).
In general a program won't keep all the content of a file in memory.
Some libraries enable you to read or write all the content at once in memory (if it fits there!). E.g. Qt has a QFile class with an inherited readAll member function.
However, file streams (either FILE
from C standard library, or std::ostream
from C++ standard library) are buffered. You may want to flush the buffer. Use std::flush (in C++) or fflush (in C); they practically often issue some system calls (probably write(2) on Linux) to ask the operating system to write some data in some file (but they probably don't guarantee that the data has reached the disk).
What exactly happens is file system-, operating system-, and hardware- specific. On Linux, the page cache may keep the data before it is written to disk (so if the computer loses power, data might be lost). And disk controller hardware also have RAM and are somehow buffering. See also sync(2) and fsync(2) (and even posix_fadvise(2)...). So even if you flush some stream, you are not sure that the bytes are permanently written on the disk (and you usually don't care).
(there are many layers and lots of buffering between your C++ code and the real hardware)
BTW you might write into memory thru std::ostringstream in C++ (or open_memstream in C on POSIX), flush that stream, then do something with its memory data (e.g. write(2) it to disk).
Related Topics
Multiplication of Two Integers in C++
Why Does This Code with '1234' Compile in C++
How to Use Std::Filesystem on Gcc 8
Variadic Template in VS 2012 (Visual C++ November 2012 Ctp)
How to Print to Console When Using Qt
Compare Double to Zero Using Epsilon
Visual C++ 2008 Express Download Link Dead
Rdrand and Rdseed Intrinsics on Various Compilers
Designated Initializers in C++20
Undefined Reference to 'Pthread_Key_Create' (Linker Error)
C++ Sizeof(Array) Return Twice the Array's Declared Length
Friend Class with Limited Access
Why Are C++ Stl iOStreams Not "Exception Friendly"