这个问题:How to protect log from application crash?引导我走向另一个问题 - std::ofstream::close()
实际上做了什么?我知道它会调用flush()
,这是一回事。但还有什么?实际关闭文件的是什么?
编辑:
让我重新解释一下我的问题 - 在调用close()
期间对实际文件执行了什么,还是只是std::ofstream
内部清理工作?
答案 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/