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

What is the difference between flush() and sync() in regard to fstream buffers?

本文关键字:区别 是什么 sync flush fstream 关于 缓冲区      更新时间:2023-10-16

我正在阅读关于I/O的cplusplus.com教程。最后,它说fstream缓冲区与磁盘

上的文件同步。

显式地,与操纵符一起使用:当某些操纵符用于流,发生显式同步。这些机械手是:flush和endl.

显式地使用成员函数sync():调用流的成员函数sync()不带参数,因此会导致即时同步。这个函数返回一个int值,等于如果流没有关联的缓冲区或失败,则返回-1。否则(如果流缓冲区已成功同步)返回0。

除了一些其他隐式情况(如destroy和stream.close())之外

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

在我的代码中,我一直使用flush()。

关于std::flush(): 的文档

刷新流缓冲区

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

std::streambuf::sync():

同步输入缓冲区与字符源

调用它来同步流缓冲区与受控序列(如文件流中的文件)。public成员函数pubsync调用这个受保护的成员函数来执行这个操作。

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

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

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

endl 当应用于ostream时,将'n'写入流,然后在该流上调用flush

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

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

c++ I/O涉及许多类之间的合作:缓冲区localelocale::facet-s。

特别是syncflush是同时存在于streamstreambuf中的成员函数,所以要注意你引用的文档,因为它们做不同的事情。

流上 flush告诉流告诉缓冲区(注意重定向)的内容刷新到目标。这可以确保没有"待挂写"。

std::endl,当与<<应用于thestream时,不超过一个

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

总是在上,sync告诉告诉缓冲区刷新内容(用于输出)并读取(用于输入)尽可能多地填充缓冲区。

注意-in buffers- sync也可以被overflow内部调用来处理"缓冲区满"(用于输出)和"缓冲区空"(用于输入)的情况。

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

endl

我的理解是:

flush()将把数据从库缓冲区中取出到操作系统的写缓冲区中,并最终导致完全同步(数据被完全写出来),但同步何时完成绝对取决于操作系统。

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

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

这是我对这个问题的理解,但当我想到它时,我不记得我是如何得到这个理解的,所以我也很好奇别人的看法。

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

没有:两者本质上都调用rdbuf()->pubsync(),然后调用std::streambuf::sync(),参见https://en.cppreference.com/w/cpp/io/basic_fstream

的链接

在构造和检查哨兵对象之后,调用rdbuf()->pubsync()

https://en.cppreference.com/w/cpp/io/basic_streambuf/pubsync

调用最派生类的sync()

唯一的区别是函数定义的位置:sync继承自istream,而flush继承自ostream (fstream继承自两者)。当然,返回值是不同的:sync返回int(0表示ok, -1表示失败),而flush返回对流对象的引用。但你可能根本不在乎这些。

输入和输出流的命名区别在于,对于输入,它"同步"。包含输入流(这里是文件)的内部缓冲区,以防发生更改或"刷新"。挂起从内部缓冲区到输出流的更改(这里还是一个文件)。即"从同步;and "flush to"更有意义的命名明智。但是对于iostream

和完整(几乎)从Emilios的回答:

std::endl,当与<<应用于thestream时,不超过一个
thestream.put('n').flush();

所以它附加一个换行符,然后调用流flush函数,然后最终调用缓冲区sync函数(通过pubsync)。
这只是一个使用行缓冲的快捷方式,即写入(直到)换行符的末尾,然后刷新所写的内容