【问题标题】:How to disable buffering on a stream?如何禁用流缓冲?
【发布时间】:2013-05-12 09:31:36
【问题描述】:

在 C 中,我可以轻松地将流设置为无缓冲 I/O:

FILE * f = fopen( "test", "r" );
setvbuf( f, (char *)NULL, _IONBF, 0 );

如何使用 C++ IOStreams 实现类似的无缓冲 I/O?

【问题讨论】:

  • 我认为 fopen() 返回 FILE* 是高级别的,它隐式地进行缓冲区管理,而使用文件描述符 open() 进行低级文件处理时,您必须显式地进行缓冲区操作。
  • @bjskishore123:这不是 C 问题,C 示例只是为了澄清我在说什么。已还原您的标签编辑。
  • @GrijeshChauhan:不。fopen() 是 ISO C,open() 是 POSIX,并且可以禁用 ISO C 函数的隐式缓冲,如我所演示的。无论如何,这完全不是问题(即“如何使用 C++ 流实现无缓冲 I/O”)。
  • 谢谢!!我不知道如何禁用隐式缓冲。
  • @GrijeshChauhan:那么请注意,在您对相关的FILE 完成任何其他操作之后,您不得致电setvbuf()(当然,fopen() 除外)。那将是UB。

标签: c++ buffer iostream


【解决方案1】:

对于文件流,您可以使用pubsetbuf

std::ifstream f;
f.rdbuf()->pubsetbuf(0, 0);
f.open("test");


说明

C++ 标准对setbuf(以及pubsetbuf)对文件流的影响做了如下说明:

如果在该流上发生任何 I/O 之前对该流调用 setbuf(0,0),则该流 变得无缓冲。否则结果是实现定义的。 “无缓冲”意味着 pbase()pptr() 总是返回 null 并且输出到文件应该尽快出现。

第一句保证上面的代码使流无缓冲。请注意,某些编译器(例如 gcc)将打开文件视为对流的 I/O 操作,因此应在打开文件之前调用 pubsetbuf(如上)。

然而,最后一句话似乎暗示这仅用于输出,而不用于输入。我不确定这是否是疏忽,或者是否有意。查阅您的编译器文档可能会很有用。例如,对于 gcc,输入和输出都是无缓冲的(参考 GNU C++ Library Manual - Stream Buffers)。

【讨论】:

  • 吹毛求疵:putsetbuf 调用 setbuf 确切的行为取决于实现。根据链接的文档,一些编译器(即 GCC)要求在打开文件之前调用它。无论如何+1找到这个。 :)
  • ...无论如何,在任何实际 I/O 发生之前。我冒昧地将答案设为“GCC 安全”。感谢您的发现!
  • @syam:setbuf(0,0) 的行为不是实现定义的;对于其他论点,它是。
  • @MichaelBurr:我不同意。 setbuf(0,0) 只需要在任何 I/O 之前禁用缓冲 if 调用,但没有其他要求。即使在 I/O 发生后,符合要求的实现也可以选择允许 setbuf(0,0) 禁用缓冲。 (同样,根据 cppreference.com 的说法——我现在还没有心深入研究标准)
  • @syam:我认为迈克尔指的是setbuf(0,0) 的行为不是实现定义的(它关闭缓冲),只是可能调用它的位置的限制。 (你可能会注意到我用作 C 示例的 setvbuf() 也需要在任何实际 I/O 之前调用。)无论如何,如果在打开文件之前调用 setbuf(0,0),你应该是安全的.
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 2012-01-31
  • 2013-05-12
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
  • 2015-08-22
  • 2010-09-11
相关资源
最近更新 更多