简体   繁体   中英

What does std::ofstream::close() actually do?

This question: How to protect log from application crash? has lead me to another - what does std::ofstream::close() actually do? I know it calls flush() and that's one thing. But what else? What closing the file actually is?

Edit: Let me rephrase my question - is anything physically done to the actual file during the call to close() or is it just std::ofstream internal cleanup stuff?

Here is the trace of calls from documentation:


void std::basic_ofstream::close();

Effectively calls rdbuf()->close() . If an error occurs during operation, setstate(failbit) is called.


std::basic_streambuf<CharT,Traits>* std::basic_ofstream::rdbuf() const;

Returns the associated stream buffer. If there is no associated stream buffer, returns NULL .


std::basic_streambuf actually inherits std::basic_filebuf , therefore:


std::basic_filebuf<CharT, Traits>* std::basic_filebuf::close();

If a put area exist (eg file was opened for writing), first calls overflow(Traits::eof()) to write all pending output to the file, including any unshift sequences.

If the most recently called function, out of underflow() , overflow() , seekpos() , and seekoff() , was overflow() , then calls std::codecvt::unshift() , perhaps multiple times, to determine the unshift sequence according to the imbued locale, and writes that sequence to file with overflow(Traits::eof()) .

Then, closes the file as if by calling std::fclose , regardless of whether any of the preceding calls succeeded or failed.

NOTE: close() is typically called through the destructor of std::basic_filebuf (which, in turn, is typically called by the destructor of std::basic_fstream .


First of all, we can see that it doesn't actually call flush() directly as you expected. Nevertheless, the flushing effect indeed occurs in the std::basic_filebuf::close() method. In addition, we can see that it still does a bit of tampering with a file, ie writing the unshift sequence. Nothing else special happens then, the file simply closes.

Pay attention to the NOTE above: in most cases you don't even need to call std::basic_ofstream::close() explicitly.

Other than flushing the userspace buffers, ie 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. Ie freeing process-associated kernel-memory.

Closes the file currently associated with the object, disassociating it from the stream.

Any pending output sequence is written to the file.

If the stream is currently not associated with any file (ie, no file has successfully been open with it), calling this function fails.

The file association of a stream is kept by its internal stream buffer: Internally, the function calls rdbuf()->close(), and sets failbit in case of failure.

Note that any open file is automatically closed when the ofstream object is destroyed.

From: http://www.cplusplus.com/reference/fstream/ofstream/close/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM