std :: ofstream :: close()实际上做了什么?

时间:2013-04-28 22:02:13

标签: c++ fstream flush

这个问题:How to protect log from application crash?引导我走向另一个问题 - std::ofstream::close()实际上做了什么?我知道它会调用flush(),这是一回事。但还有什么?实际关闭文件的是什么?

编辑: 让我重新解释一下我的问题 - 在调用close()期间对实际文件执行了什么,还是只是std::ofstream内部清理工作?

3 个答案:

答案 0 :(得分:4)

除了刷新用户空间缓冲区,即flush(),在底层文件描述符上调用close(2)。这取决于操作系统当时会发生什么,但很可能没有任何事情发生在文件占用的实际存储空间中。

发生的是(如果文件描述符是该文件的该进程中的最后一个引用)与该文件关联的文件条目将从该进程的打开文件表中删除。即释放与进程相关的内核内存。

答案 1 :(得分:4)

以下是来自文档的调用记录:


void std::basic_ofstream::close();

有效拨打rdbuf()->close()。如果在操作期间发生错误,则会调用setstate(failbit)


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

返回关联的流缓冲区。如果没有关联的流缓冲区,则返回NULL


std::basic_streambuf实际上继承了std::basic_filebuf,因此:


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

如果存在放置区域(例如,文件已打开以进行写入),则首先调用overflow(Traits::eof())将所有挂起的输出写入文件,包括任何非移位序列。

如果underflow()overflow()seekpos()seekoff()中最近调用的函数为overflow(),则调用std::codecvt::unshift()或许多次,根据嵌入的语言环境确定非移位序列,并使用overflow(Traits::eof())将该序列写入文件。

然后,关闭文件就好像通过调用std::fclose一样,无论前面的任何调用是成功还是失败。

注意: close()通常是通过std::basic_filebuf的析构函数调用的(反过来,它通常由std::basic_fstream的析构函数调用。


首先,我们可以看到它实际上并没有像您预期的那样直接调用flush()。然而,刷新效果确实发生在std::basic_filebuf::close()方法中。另外,我们可以看到它仍然会对文件进行一些篡改,即写入非移位序列。没有其他特殊的事情发生,文件只是关闭。

请注意上面的注意:在大多数情况下,您甚至不需要明确调用std::basic_ofstream::close()

答案 2 :(得分:1)

关闭当前与该对象关联的文件,将其与该流取消关联。

将任何挂起的输出序列写入文件。

如果流当前未与任何文件关联(即,没有文件成功打开),则调用此函数将失败。

流的文件关联由其内部流缓冲区保存: 在内部,该函数调用rdbuf() - &gt; close(),并在发生故障时设置failbit。

请注意,当ofstream对象被销毁时,任何打开的文件都会自动关闭。

来自:http://www.cplusplus.com/reference/fstream/ofstream/close/