不可不知的Linux中三种缓冲模式

今天来说说缓冲的事。也许你已经听说过三种缓冲模式。标准I/O库的缓冲主要分为3种:全缓冲、行缓冲和不缓冲。今天就3种缓冲写了一些示例,以帮助理解。

I/O文件流的缓冲类型

标准IO提供缓冲的目的是为了通过减少使用read和write调用的次数来提高IO读写的效率,它对每个IO流自动的进行缓冲处理,从而避免了用户程序在使用read和write需要考虑的这一点。因为read和write是系统调用。《可以参考Linux 系统调用和库函数

标准IO流提供了三种缓冲。分别是全缓冲,行缓冲以及无缓冲。

全缓冲

在使用全缓冲的情况下,当数据填满整个缓冲区之后才进行实际的IO操作。对于驻留在磁盘上的文件的读写通常是使用全缓冲。

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char const *argv[])
{
	
	FILE *fp;

	if ((fp = fopen("./text.txt","w+")) == NULL){

		printf("open file failed\n");
		
		return -1;
	}

	char buf[] = "minger\n";

	fwrite(buf,sizeof(char),sizeof(buf),fp);

    //fflush(fp);
	sleep(20); //延时一段时间,以便观察。

	fclose(fp);

	return 0;
}





编译输出:

$ gcc main -o main.c
$ ./main

编译执行这个程序,然后立马查看text.txt文件
在这里插入图片描述
会发现文件的长度是0,原因在于它默认是全缓冲的,因此在将内容写入文件后,并没有直接存在文件中,当程序关闭文件或者程序运行完成退出后,再次查看:

在这里插入图片描述

除了等待程序运行完成,还可以使用fflush函数。fflush函数根据指定的文件流将缓冲区的内容进行实际的操作,并清空缓冲区;如果参数为NULL,则会对所有打开的文件流操作。

所以将fwrite下面一行的注释去掉后,就可以发现,写入之后,就可以直接在文件中看到内容了。

行缓冲

在使用行缓冲的情况下,每当输入输出遇到换行或者缓冲区满了的情况下才会进行实际的IO操作,当涉及到终端输入输出的时候通常使用行缓冲。

例子举例:

#include <stdio.h>


int main(int argc, char const *argv[])
{
	
	printf("hello,minger");
	//fflush(stdout);//人为刷新缓冲区
	while(1);

	return 0;
}

编译运行:

$ gcc main.c -o main
$ ./main

你会发现,printf执行完了之后,内容并没有马上输出到终端。

原因是printf 是标准I/O库函数,往标准输出输出东西,是行缓冲,因为输出的东西换行符, 所以数据存放在缓冲区中,没有刷新缓冲区。故不能输出到屏幕上。

可以把注释函数fflush打开就可能在终端显示输出信息啦。

或者,要想打印完后直接输出到终端,只需要改成下面这样就可以了:

printf("hello,minger\n");

不带缓冲

此时标准IO库不对字符进行缓冲存储。这就使得输入流要求IO立即进行,如标准错误流,若果出现错误,会立马输出。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{

	
	fprintf(stderr,"hello,minger");
	sleep(10);

	return 0;
}

编译运行:
在这里插入图片描述
编译运行你就会发现,运行完fprintf语句后,内容直接输出在终端,而不需要等到换行。一般来说,标准错误是不带缓冲的。

总结

标准错误永远是无缓冲的。当标准输入输出指向的是交互式设备(如终端)的时候,它们是行缓冲的。若不是则是全缓冲的。

在这里插入图片描述

欢迎关注公众号【程序猿编码】,添加本人微信号(17865354792),回复:领取学习资料。进入技术交流群。网盘资料有如下:

在这里插入图片描述

发布了131 篇原创文章 · 获赞 115 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/chen1415886044/article/details/105326036