Liunx中文件操作的三种缓存模式

目录

1 缓存的概念

1.2 行缓存

 1.3全缓存(块缓存)

1.4无缓存

2.函数的缓存方式

2.1 fputc函数论证

2.1.1 标准输出默认缓存方式

2.1.2 自定义缓存方式 

 2.2 fwrite函数论证

2.2.1 标准输出默认缓存方式

2.2.2 自定义缓存方式

 


 简介:C库三种缓存模式,行缓存、全缓存、无缓存,你认为库函数的缓存方式是怎么样的,这篇文章通过几个函数来论证一下。

1 缓存的概念

1.程序中的缓存,位于用户空间----用户空间的缓存

2.每打开一个文件,内核在内核空间中也会开辟一块缓存,这个叫内核空间的缓存

        文件IO中的写即是将用户空间中的缓存写到内核空间的缓存中。

        文件IO中的读即是将内核空间的缓存写到用户空间中的缓存中。

3.标准IO的库函数中也有一个缓存,这个缓存称为----库缓存

C库缓存的特点:

1.遇到\n 时,会将库缓存的内容写到内核缓存中,即调用了系统调用函数。

2.库缓存写满时,会调用系统调用函数,将库缓存内容写到内核缓存中,***长度为1024字节***

#include <stdio.h>

int main()
{
    printf("hello world");
    while(1);                 //让程序一直在此,程序结束也会将缓存中的数据写入到内存或者磁盘中。
    return 0;
}

a9ae9ade2fe14cef82458ad5a012bf6f.jpeg

图七 

1.2 行缓存

遇到\n,或者写满缓存时,调用系统调用函数与内核交互。

写:puts,putchar,printf
读:getchar

 1.3全缓存(块缓存)

只有写满缓存,或者fflush强制刷新缓存,才调用系统调用函数。

1.4无缓存

输出错误信息:stderr

stderr和stdout虽说都能在终端输出,但两个是不同的输出流。 

2.函数的缓存方式

        根据下面例子的验证,函数的缓存方式没有限制,函数的缓存方式是根据文件的缓存机制确定的,向终端中输入或输出为行缓存,普通文件输入读出为全缓存(除printf,putchar,puts,getchar···默认输出到终端,因为输出到终端的原因所以为行缓存,其实标准输入输出的缓存模式也可以通过setbuf函数改变)。

2.1 fputc函数论证

2.1.1 标准输出默认缓存方式

#include <stdio.h>

int main()
{
    fputc('x', stdout);
    //fputc('\n', stdout);   验证行缓存
    while(1);
    return 0;
}

终端输出 

e8a3f73433004c9eaccdea7202b95a75.jpeg

2.1.2 自定义缓存方式 

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

int main(int argc, char **argv)   //argc:终端输入参数的个数,如./a.out test.txt, argv = 2;
                                  //argv: 输入的参数字符串数组,如./a.out test.txt,
                                  //argv[1]=./a.out, argv[2]=test.txt
{
        if(argc<2)
        {
                printf("input para less than 2\n");
                exit(1);
        }
        FILE* fp;
        int nRet = 0;
        char buf[8000];
        setbuf(stdout, buf);    //改变标准输出的缓存方式为全缓存。
        fp = fopen(argv[1], "r");
        if(fp == NULL)
        {
                perror("fopen");
                exit(1);
        }
        while(1)
        {
                nRet = fgetc(fp);
                if(!feof(fp)) break;
                fputc(nRet, stdout);
        }
        //fflush(fp);     刷新缓存,判断全缓存
        while(1);
        fclose(fp);
        return 0;
}

终端输出

789b1eb32317486c8bc87774d4497df1.jpeg

 2.2 fwrite函数论证

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

int main()
{
	FILE* fp;
	int nRet = 0;
	int count =0;
	char buf[] = "hello world\n";
	//char fullbuf[2000];
	//setbuf(stdout, fullbuf);    //change the cache mode of stdout
	if(fwrite(buf, strlen(buf), 1,stdout)<1)
	{
		perror("fwrite");
		exit(1);
	}

	while(1);
	fclose(fp);
	return 0;
}

2.2.1 标准输出默认缓存方式

5c249d0c04cb4e279f725acd0bcbd47e.jpeg

2.2.2 自定义缓存方式

上面的文件取消这两条注释即可

    char fullbuf[2000];
    setbuf(stdout, fullbuf);    //change the cache mode of stdout

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

int main()
{
	FILE* fp;
	int nRet = 0;
	int count =0;
	char buf[] = "hello world\n";
	char fullbuf[2000];
	setbuf(stdout, fullbuf);    //change the cache mode of stdout
	if(fwrite(buf, strlen(buf), 1,stdout)<1)
	{
		perror("fwrite");
		exit(1);
	}

	while(1);
	fclose(fp);
	return 0;
}

 终端输出

54b810fc7a7444ec82b425ed2e6b41bd.jpeg

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值