关于fstream缓冲区,flush()和sync()有什么区别?

时间:2013-01-10 06:15:57

标签: c++ stream buffer fstream ostream

我正在阅读cplusplus.com tutorial on I/O。最后,它说fstream缓冲区与光盘上的文件同步

  

明确地,使用操纵器:当使用某些操纵器时   流,显式同步发生。这些操纵者   是:flush和endl。

  

明确地,使用成员函数sync():调用   stream的成员函数sync(),它不带参数,导致   立即同步。此函数返回一个等于的int值   如果流没有关联的缓冲区或出现故障,则返回-1。否则(如果流缓冲区已成功同步)   返回0。

除了一些其他隐式案例(例如destroy和stream.close())

调用fstream :: flush()和fstream :: sync()有什么区别? ENDL?

在我的代码中,我总是使用flush()。

std :: flush()的文档:

  

刷新流缓冲区

     

同步与流关联的缓冲区   到其受控的输出序列。这实际上意味着所有   缓冲区中的未写入字符被写入其受控制的字符   输出顺序尽快(“刷新”)。

std :: streambuf :: sync()的文档:

  

将输入缓冲区与字符源同步

     

调用它来使流缓冲区与受控序列同步(就像文件流中的文件一样)。公共成员函数pubsync调用此受保护的成员函数来执行此操作。

如果这是一个新手问题,请原谅我;我是个菜鸟。

4 个答案:

答案 0 :(得分:14)

<强> basic_ostream ::冲洗 这是一个非虚拟函数,它将未经修改的更改写入底层缓冲区。如果出现错误,它会在使用的流对象中设置错误标志。这是因为返回值是对流本身的引用,以允许链接。

<强> basic_filebuf ::同步 这是一个虚拟函数,它将所有挂起的更改写入基础文件,并返回错误代码以表示成功或失败。

<强> ENDL 当应用于ostream时,会将'\n'写入流,然后在该流上调用flush

因此,基本上:flush是任何流的更通用的函数,而sync显式绑定到文件。 flush是非虚拟的,而sync是虚拟的。这改变了在继承的情况下如何通过指针(到基类)使用它们。此外,他们报告错误的方式不同。

答案 1 :(得分:5)

syncinput个流的成员,所有未读的字符都从缓冲区中清除。 flushoutput个流的成员,缓冲的输出传递给内核。

答案 2 :(得分:4)

C ++ I / O涉及许多类之间的协作: stream buffer locale locale :: facet -s

特别是syncflushstreamstreambuf中存在的成员函数,因此请注意您所引用的文档,因为它们执行不同的操作。

On streams flush告诉流告诉缓冲区(注意重定向)其内容刷新到目标上。这样可以确保没有“待处理写入”。

std::endl,当thestream<<一起使用时,只不过是

thestream.put('\n'); thestream.flush();

始终在上,sync告诉告诉缓冲区 flush 内容(用于输出)和读取(用于输入)尽可能多地重新填充缓冲区。

请注意-in buffers - overflow内部也可以调用sync来处理“buffer full”(用于输出)和“buffer empty”(用于输入)情况。

我因此感觉到,sync更像是一个“内部”函数,用于流缓冲通信和缓冲区实现(在不同的缓冲区类型中虚拟和覆盖),而flush则很多更多流和客户端程序之间的接口。

endl ...只是一条捷径。

答案 3 :(得分:1)

我理解如下:

flush()会将数据库中的数据从操作系统的写入缓冲区中取出并最终导致完全同步(数据被完全写出),但是当同步到时,它肯定取决于操作系统完整。

sync()将尽可能在给定的操作系统中尝试强制实现完全同步 - 但所涉及的操作系统可能会或可能不会促进此操作。

所以flush()是:从缓冲区中获取数据并在行中写入 sync()是:如果可能的话,现在强制数据被明确写出来。

这是我对此的理解,但正如我想的那样,我不记得我是如何达成这种理解的,所以我很想听到别人的意见。