11

这个问题:如何保护日志免受应用程序崩溃?已将我引向另一个-std::ofstream::close()实际上是做什么的?我知道它会打电话flush(),这是一回事。但还有什么?关闭文件实际上是什么?

编辑:让我重新表述我的问题 -在调用过程中对实际文件进行了物理close()处理还是只是std::ofstream内部清理的东西?

4

3 回答 3

8

以下是来自文档的调用跟踪:


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())将所有挂起的输出写入文件,包括任何取消移位序列。

如果最近调用的函数 out of underflow(), overflow(),seekpos()seekoff(), 是,则可能多次overflow()调用,以根据注入的语言环境确定 unshift 序列,并将该序列写入文件 with 。std::codecvt::unshift()overflow(Traits::eof())

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

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


首先,我们可以看到它实际上并没有flush()像您预期的那样直接调用。然而,该方法中确实出现了冲洗std::basic_filebuf::close()效果。此外,我们可以看到它仍然对文件进行了一些篡改,即写入 unshift 序列。然后没有什么特别的事情发生,文件只是关闭。

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

于 2013-04-28T22:27:46.650 回答
7

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

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

于 2013-04-28T22:14:06.720 回答
2

关闭当前与对象关联的文件,将其与流解除关联。

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

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

流的文件关联由其内部流缓冲区保存:在内部,函数调用 rdbuf()->close(),并在失败时设置 failbit。

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

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

于 2013-04-28T22:03:38.173 回答