首页 > 解决方案 > 了解输出流、缓冲和刷新

问题描述

为了输出,我们必须使用 << 运算符将流定向到 cout 对象。<< 运算符在这种情况下用作输出运算符,因此如果我们需要按位左移运算符,我们必须将包含它的表达式括在括号中。

我们在终端中看到的打印内容是对缓冲区存储内容的一瞥。如果没有显式刷新(使用 endl 或 flush),我们将看不到这些内容,例如在文本文件中。这与我们在编辑 MS Word 文档但未保存实际更改后看到的内容相当。不冲洗输出就像用双臂捡起多个盒子并放入目标位置一次。使用冲洗输出就像一个一个地挑选和放置盒子——就像我在这个现实生活中的例子中所说的那样,它需要更多的时间。

总体而言,在基于终端的可执行文件中,刷新不是非常必要的,因为正如我在开始时所说的那样,我们可以查看缓冲区并查看发生了什么。虽然,如果我们要为我们的程序制作实时日志,则可能需要刷新。

标签: c++

解决方案


终端不会“窥视”输出,它会显示给定的内容,当给定要显示的数据时

对于基本上意味着实时的无缓冲输出流。对于缓冲的输出流,例如ofstreamoperator<<提供,这意味着何时刷新缓冲区,或者缓冲区已满并且无论如何都必须刷新。这实际上是一种自动冲洗。

同样的行为适用于文件,没有区别。当数据被刷新时,它会出现在文件中,但不会出现在之前。您可以使用诸如tail -f.

在您的终端应用程序中需要刷新。如果您正在使用std::endl,那么您已经在行尾冲洗,因此您可能不会注意到任何问题。如果您使用"\n",您可能需要定期手动刷新,或者您可能会注意到您的输出停止,直到累积到足以值得自动刷新为止。

在像 C++ 这样的语言中,有两种类型的“写入”调用,一种写入缓冲区,另一种使用操作系统调用进行写入。缓冲区可能会或可能不会隐式链接到文件。诸如可以写入的缓冲区之类的东西std::stringstream,但它们没有链接到文件。

还有write()一个没有缓冲区,并且每一位数据都会立即推送到相关的接收器,无论是文件、管道进程、网络套接字还是其他。

这里要学习的重要一点是有用户空间写入操作系统写入。前者只是在您的流程中移动数据,它不会离开,就像在缓冲区的情况下一样。后者涉及将数据从用户进程移动到内核,并可能转发到另一个进程或文件。

从“缓冲区窥视”的角度来看,这意味着这实际上是不可能的,一个进程在没有某种异常权限的情况下无法查看另一个进程的内容,例如作为调试器附加。在正常操作中,这永远不会发生。所有进程间通信都由内核调解。


推荐阅读