18 缓冲问题

缓冲方式

涉及到不同的输出终端,自然涉及到一个问题:缓冲。

在C语言中基于流的 I/O 提供了 3 种缓冲:

全缓冲

直到缓冲区被填满,才调用系统 I/O 函数。

  • 对于读操作来说,直到读入内容的字节数等于缓冲区大小或者文件已经到达结尾,才进行实际的 I/O 操作,将外存文件内容读入缓冲区
  • 对于写操作来说,直到缓冲区被填满,才进行实际的 I/O 操作,缓冲区内容写到外存文件中

磁盘文件通常是全缓冲的。

行缓冲

直到遇到换行符 ‘\n’,才调用系统 I/O 库函数。

  • 对于读操作来说,遇到换行符 ‘\n’ 才进行 I/O 操作,将所读内容读入缓冲区
  • 对于写操作来说,遇到换行符 ‘\n’ 才进行 I/O 操作,将缓冲区内容写到外存中

由于缓冲区的大小是有限的,所以当缓冲区被填满时,即使没有遇到换行符‘\n’,也同样会进行实际的 I/O 操作。

标准输入 stdin 和标准输出 stdout 默认都是行缓冲的。

无缓冲

没有缓冲区,数据会立即读入或者输出到外存文件和设备上。

标准错误 stderr 是无缓冲的,这样保证错误提示和输出能够及时反馈给用户,供用户排除错误。

go中的缓冲方式

官方回答,go中os.Stdinos.Stdoutos.Stderr都是无缓冲的,因为它的类型实际上是 *os.File,很显然 *os.File 是无缓冲的。

Go 中如果需要缓冲,请使用 bufio 包,特殊的需求,可以基于它进行扩展。

上次修改: 20 July 2020