标准I/O提供了三种类型的缓冲。
- 全缓冲: 在填满标准I/O缓冲区后才进行实际I/O操作。对于驻留在磁盘上的文件通常是有标准I/O库实施全缓冲。
- 行缓冲: 当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。当涉及一个终端(例如标准输入和输出),通常使用行缓冲。对于行缓冲有两个限制。第一,因为标准I/O库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲区,那么即使还没有写一个换行符,也进行I/O操作。第二,任何时候只要通过标准I/O库要求从(a)一个不带缓冲的流,或者(b)一个行缓冲的流(它要求从内核得到数据)得到输入数据,那么就会造成冲洗所有行缓冲输出流。
- 不带缓冲: 标准I/O库部队字符进行行缓冲存储。
标准出错流stderr通常是不带缓冲的,这就使得出错信息可以尽快显示出来,而不管它们时候含有一个换行符。
ISO C要求下列缓冲特征:
- 当且仅当标准输入和标准输出并不涉及交互式设备是,它们才是全缓冲的。
- 标准出错决不会是全缓冲的。
很多系统默认使用下列类型的缓冲:
- 标准出错是不带缓冲的。
- 如若是涉及终端设备的其他流,则它们是行缓冲的,否则是全缓冲的。
标准出错是不带缓冲的,打开至终端设备的流是行缓冲的;其他所有流则是全缓冲的。
可调用下列两个函数中的一个更改缓冲类型:
- #include <stdio.h>
- void setbuf(FILE *restrict fp, char *restrict buf);
- void setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
返回值:成功返回0,出错返回非0值
可以使用setbuf函数打开或关闭缓冲机制。通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可将其设置为行缓冲。为了关闭缓冲,将buf设置为NULL。
使用setvbuf,我们可以精确地指定所需的缓冲类型。这是用mode参数实现的:
- _IOFBF 全缓冲
- _IOLBF 行缓冲
- _IONBF 不带缓冲
如果指定一个不带缓冲的流,则忽略buf和size参数。如果指定全缓冲或行缓冲,则buf和size可选择地指定一个缓冲区及其长度。如果该流是带缓冲的,而buf是NULL,则标准I/O库将自动地为该流分配适当长度的缓冲区。适当长度指的是由常量BUFSIZE所指定的值。
如果一个函数内分配一个自动变量类的标准I/O缓冲区,则从该函数返回之前,必须关闭该流。另外,有些实现将缓冲区的一部分用于存放它自己的管理操作信息,所以可以存放缓冲区中的实际数据字节少于size。一般而言,应由系统选择缓冲区的长度,并自动分配缓冲区。在这种情况下关闭此流时,标准I/O库将自动释放缓冲区。
任何时候,都可以强制冲洗一个流
- #include <stdio.h>
- int fflush(FILE *fp);
返回值:成功返回0,出错返回EOF
此函数使该流所有未写的数据都被传送至内核。作为一个特例,如若fp是NULL,则此函数将导致所有输出流被冲洗。