2022-10-22 IO缓冲区

常见的显示器、硬盘、键盘和鼠标都被称为IO设备,这里面的“I”就是Input,“O”就是Output,合起来就是输入输出设备的意思。I/O设备的访问速度与CPU的速度相差好几个数量级,为了协调IO设备与CPU速度,设计出了IO缓冲区。当应用程序将要读取某块数据的时候,如果这块数据已经存放在缓冲区中,那么就可以立即返回给程序,而不需要经过实际的读取设备操作。当然,如果数据在读取之前并未被存入缓冲区,那么系统会将一大块数据从设备先读取到缓冲区中。对于写入操作来说也是同样的道理,通常应用程序也会先将数据陆续写入缓冲区中,直到缓冲区被写满或者文件关闭时才一次性地写入设备中。

由于getchar函数是阻塞函数,也就是说只要该函数没有完成调用,程序就会卡在那里不动,直到函数返回。这时候不要输入任何数据(阻止程序结束),而是打开另-一 个终端,使用cat命令查看output.txt文件是否有数据写入:

此时output.txt文件已经被创建了( fopen函数调用时创建的),但是里面却没有任何数据,因为此时的数据在缓冲区里。在第一个终端里输入任意字符,调用fclose函数关闭文件后,缓冲区里的数据才被写入文件中:

如果希望立即将数据写入设备中,可以使用fflush函数:

#include

...

int fflush(FILE *stream) ;

标准IO提供了三种类型的缓冲模式:按块缓存、按行缓存和不缓存。

按块缓存也称为全缓存,即在填满缓冲区后才进行实际的设备读写操作;按行缓存是指在接收到换行符("n')之前,数据都是先缓存在缓冲区的:最后一个是不缓存,也就是允许直接读写设备上的数据。

C语言允许通过setvbuf函数自定义缓存的模式:

#include

...

int setvbuf (FILE *stream, char *buf, int mode, size t size) ;

setvbuf函数有四个参数:第一个参数是一个 FLE结构的指针,指向个待操作的文件流:第二个参数指定一个用户分配的缓冲区,如果该参数设置为NULL,那么函数会自动分配一个指定尺寸的缓冲区:第三个参数指定了缓存模式,_IONBF参数指定缓冲区的实际尺寸。


程序停止,并没有将所有的字符串都打印出来,这是因为前面调用setvbuf函数设置了按块缓存的缘故。由于fflush函数“截胡”,本来应该存放在缓冲区的“Welcome to bbs.fishc.com”字符串被强制写入设备中:而后面继续写入的字符串则继续被塞进了缓冲区里,直到用户输入任意字符结束程序,缓冲区里面的数据才写入设备:

你可能感兴趣的:(2022-10-22 IO缓冲区)