Linux文件缓冲区

1. 数据缓冲区

C 程序员经常使用动态分配的缓冲区(通过调用 malloc() / free() 函数)在函数之间传递数据

2. 为什么需要缓冲

首先在若干字符作为一个块传输比逐个发送字符耗费的时间少。其次如果你输入有误。就可以使用您的键盘更改功能来修正错误。并且最终按下回车,就可以发送正确的输入

3. 缓冲区的分类

缓冲分为两类,完全缓冲和行缓冲

1.对于完全缓冲来说,缓冲区满时,缓冲区会被清空。此时缓冲区中的内容也会发往目的地。这种类型的缓冲通常出现在文件输入中。第一次执行I/O操作时,ANSI标准的文件管理函数通过调用malloc函数获得需要使用的缓冲区,默认大小为8192

//come from /usr/include/stdio.h
#ifndef BUFSIZ
# define BUFSIZ _IO_BUFSIZ        //BUFSIZ 全局宏定义
#endif
//come from /usr/include/libio.h
#define _IO_BUFSIZ _G_BUFSIZ
//come from /usr/include/_g_config.h
#define _G_BUFSIZ 8192        //真实大小

2.对于行缓冲来说,遇到一个换行字符时,缓冲区中的内容就会被清空。因为标准I/O库每行的缓冲区长度是固定的,所以只要填满了缓冲区,即使还没有遇到换行符,也会执行I/O系统调用操作,默认行缓冲区的大小为1024
1024
1025

4. 缓冲区机制

对文件的访问可以分为带缓冲区的操作和非缓冲区的文件操作

  1. 带缓冲区文件操作:高级标准文件I/O操作,将会在用户空间中自动为正在使用的文件开辟内存缓冲区
  2. 非缓冲区文件操作:低级文件I/O操作,读写文件时,不会开辟对文件操作的缓冲区,直接通过系统调用对磁盘进行操作(读、写等),当然用于可以在自己的程序中为每个文件设定缓冲区

两种文件操作的解释和比较:

  1. ANSI标准C库函数 是建立在底层的系统调用之上,ANSI标准C库中的文件处理函数为了减少使用系统调用的次数,提高效率,采用缓冲机制,这样,可以在磁盘文件进行操作时,可以一次从文件中读出大量的数据到缓冲区中,以后对这部分的访问就不需要再使用系统调用了,即需要少量的CPU状态切换,提高了效率
  2. 非缓冲的文件操作访问方式,每次对文件进行一次读写操作时,都需要使用读写系统调用来处理此操作,即需要执行一次系统调用,执行一次系统调用将涉及到CPU状态的切换,即从用户空间切换到内核空间,实现进程上下文的切换,这将损耗一定的CPU时间,频繁的磁盘访问对程序的执行效率造成很大的影响

fopen打开普通文件,用open打开设备文件

5. 无缓冲区

无缓冲区是指标准I/O库不对字符进行缓存,直接调用系统调用。标准出错流stderr通常是不带缓冲区的,这使得出错信息能够尽快地显示出来。

注:①标准输入和标准输出设备:当且仅当不涉及交互作用设备时,标准输入流和标准输出流才是全缓冲的。②标准错误输出设备:标准出错绝不会是全缓冲方式的

6. 更改缓冲区类型

void setbuf(FILE *steam, char *buf);
说明:setbuf函数具有打开和关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中)的缓冲区。通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可以将其设置为行缓冲。为了关闭缓冲,可以将buf参数设置为NULL

char outbuf[50];
int main(void)
{
    /* 将outbuf与stdout输出流相连接 */
    setbuf(stdout,outbuf);
    /* 向stdout中放入一些字符串 */
    puts("hello furong.");
    //fflush(stdout);
    /* 以下是outbuf中的内容 */
    puts(outbuf);
    /*刷新流*/
    fflush(stdout);
    return 0;
}

fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准]
fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
printf(” “);后面加fflush(stdout);可提高打印效率

int setvbuf(FILE *stream, char *buf, int type, unsigned size);

type : 缓冲区的类型:
_IOFBF(满缓冲):当缓冲区为空时,从流读入数据。或者当缓冲区满时,向流写入数 据
_IOLBF(行缓冲):每次从流中读入一行数据或向流中写入一行数据
_IONBF(无缓冲):直接从流中读入数据或直接向流中写入数据,而没有缓冲区
size : 缓冲区内字节的数量

如果出现指定该流是带缓冲区的,而buf 是NULL,则标准I/O 库将自动为该流分配适当长度的缓冲,适当长度指的即是由文件属性数据结构(struct stat)的成员st_blksize 所指定的值,如果系统不能为该流决定此值(例如若此流涉及一个设备或一个管道),则分配长度BUFSIZ 的缓冲区

setvbuf(fp,NULL,_IONBF,0);
setvbuf(fp,buf,_IOLBF,sizeof(buf)); 
setvbuf(fp,buf,_IOFBF,sizeof(buf));

注意:This function should be called once the file associated with the stream has already been opened but before any input or output operation has taken place.
意思是这个函数应该在打开流后,立即调用,在任何对该流做输入输出前

7. 缓冲

操作系统以缓冲方式实现设备的输入和输出操作,主要是缓解处理机与设备之间速度不匹配的矛盾

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值