【问题标题】:What does std::ofstream::close() actually do?std::ofstream::close() 实际上做了什么?
【发布时间】:2013-04-22 12:23:36
【问题描述】:

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

编辑: 让我重新表述我的问题 - 在调用 close() 期间是否对实际文件进行了物理处理,还是只是 std::ofstream 内部清理工作?

【问题讨论】:

    标签: c++ fstream flush


    【解决方案1】:

    这是来自文档的调用跟踪:


    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();
    

    如果存在 put 区域(例如,打开文件进行写入),首先调用 overflow(Traits::eof()) 将所有待处理的输出写入文件,包括任何 unshift 序列。

    如果在underflow()overflow()seekpos()seekoff() 中最近调用的函数是overflow(),则调用std::codecvt::unshift(),可能多次调用,以根据到被灌输的语言环境,并用overflow(Traits::eof())将该序列写入文件。

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

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


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

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

    【讨论】:

    • “取消移位序列”?那是什么?
    【解决方案2】:

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

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

    【讨论】:

    • >除了刷新用户空间缓冲区,即flush()close(2) 在底层文件描述符上调用。 回复:哪个flush()?你的意思是std::ofstream::flush()fflush(3) 或?
    【解决方案3】:

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

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

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

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

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

    发件人:http://www.cplusplus.com/reference/fstream/ofstream/close/

    【讨论】:

    • 我已经改写了我的问题,请参阅原帖的编辑。
    • >请注意,当 ofstream 对象被销毁时,任何打开的文件都会自动关闭。 回复:程序崩溃时ofstream对象会被auto销毁吗?我认为答案是否定的。
    猜你喜欢
    • 2013-06-02
    • 2020-11-21
    • 2015-02-26
    • 2017-06-29
    • 2013-06-13
    • 2021-10-25
    • 2011-08-12
    • 1970-01-01
    • 2010-11-27
    相关资源
    最近更新 更多