在关闭fstream之前,如何确保将数据写入磁盘?

时间:2011-09-22 23:02:42

标签: c++ fstream

以下看起来很合理,但我听说理论上数据理论上仍然可以在缓冲区而不是磁盘上,即使在close()调用之后也是如此。

#include <fstream>

int main()
{
    ofstream fsi("test.txt");

    fsi << "Hello World";

    fsi.flush();

    fsi.close();

    return 0;
}

7 个答案:

答案 0 :(得分:4)

您无法使用标准工具,并且必须依赖操作系统设施。 对于POSIX fsync应该是你需要的。由于无法从标准流中获取C文件描述符,因此您必须在整个应用程序中使用C流,或者只是打开文件以刷新执行磁盘。或者,有sync,但这会刷新所有缓冲区,您的用户和其他应用程序将讨厌这些缓冲区。

答案 1 :(得分:1)

您可以保证通过刷新流将缓冲区中的数据写入磁盘。这可以通过调用flush()成员函数,flush操纵符,endl操纵符来完成。

但是,在您的情况下没有必要这样做,因为close保证将任何挂起的输出序列写入物理文件。

  

§27.9.1.4/ 6:

     

basic_filebuf&LT; charT,traits&gt; * close();

     

效果:如果is_open()== false,则返回空指针。如果存在put区域,则调用overflow(traits :: eof())到fl ush字符。 (...)

答案 2 :(得分:0)

  

§27.9.1.4
  basic_filebuf * close();
  效果:如果is_open()== false,则返回空指针。 如果放置区域   存在,调用overflow(traits :: eof())来刷新字符。如果是最后一个   调用虚拟成员函数* this(在下溢,溢出之间,   seekoff和seekpos)溢出然后调用a_codecvt.unshift   (可能几次)确定终止序列,插入   那些字符和调用再次溢出(traits :: eof())。最后,   无论前面的任何一个调用是否失败或抛出一个   异常,该函数关闭文件(就像通过调用一样)   的std :: FCLOSE(文件))。如果该功能发出任何调用,   包括std :: fclose,失败,通过返回空指针关闭失败。   如果其中一个调用抛出异常,则会捕获异常   关闭文件后重新开始。

保证刷新文件。但请注意, OS 可能会将其缓存,并且 OS 可能不会立即刷新它。

答案 3 :(得分:0)

您使用的是哪种操作系统?

您需要使用Direct(非缓冲)I / O来保证数据直接写入物理设备,而无需访问文件系统写入缓存。请注意,在进行物理编写之前,仍然必须通过磁盘缓存。

在Windows上,您可以在打开文件时使用FILE_FLAG_WRITE_THROUGH标志。

答案 4 :(得分:-1)

close()成员函数关闭底层OS文件描述符。此时,该文件应该在磁盘上。

答案 5 :(得分:-1)

我很确定调用close()的重点是刷新缓冲区。 This site同意。虽然取决于您的文件系统和安装设置,但仅仅因为您已经“写入磁盘”并不意味着您的文件系统驱动程序和磁盘硬件实际上已经获取了数据并在物理金属片上制作了磁性位。它可能仍然在磁盘缓冲区中。

答案 6 :(得分:-2)

关闭之前如何abt flushing