11-2 文件流的缓冲

本文介绍了文件流缓冲的概念,旨在提高CPU效率和减少IO操作。通过设置缓冲区,如使用setbuf()和setvbuf()函数,可以优化文件读写过程。缓冲区的大小可以根据需求调整,并且在适当的时候使用fflush()函数清空缓冲区,确保数据即时输出。理解缓冲区的工作原理和管理对于提升程序性能至关重要。
摘要由CSDN通过智能技术生成

1. 缓冲的来源

        通常,文件数据的读写效率远低于内存读写效率。如果不存在缓冲,CPU 在读取文件数据时需要先发送指令给 DMA(专门处理 IO 数据读写的硬件),而后 DMA 从文件数据读取一个 0 到内存,CPU 再处理该数据。此过程 CPU 全程参加,极大浪费了 CPU 资源。

        文件流缓冲的目的正是降低 IO 对于 CPU 占用。如图所示,在添加缓冲区后,DMA 可以将文件数据先读取到缓冲区中,等待缓冲区满时,再通知 CPU,此时 CPU 将缓冲区的数据读取并处理。

 2. 设置缓冲区大小

        可使用函数 setbuf() 和 setvbuf() 设置缓冲区

        setbuf() 函数接收两个参数,一是文件指针,二是缓冲区的指针。setbuf() 的缺点在于无法设置缓冲区大小。原因是传入参数为缓冲区指针的情况下,仅知道缓冲区的起始地址,并不知道缓冲区的结束地址,故无法设置其大小。通常情况下,编译器设定 setbuf() 函数的缓冲区大小为 BUFSIZ 

char buf[BUFSIZ];
setbuf(file, buf);

        setvbuf() 函数可以设置缓冲区大小。其接收四个参数,前两个参数与 setbuf() 函数相同,第三个参数为缓冲方式( _IOFBF 全量缓冲,_IOLBF 按行缓冲,_IONBF 禁用缓冲),第四个参数为缓冲区大小。

char buf[8192];
setvbuf(file, buf, _IOFBF, 8192);

 3. 缓冲区的生命周期和清空

        缓冲区的生命周期需要大于等于文件流的生命周期。通常可以利用 malloc() 函数,指定一块内存当做缓冲区,等到文件流关闭后再释放该内存。

        清空缓存区需要利用函数 fflush() 函数,其可以将缓冲区数据直接读取,不必等缓冲区结束。以控制台输出对应的 stdout 文件指针为例,通常在 debug 代码过程中,控制台不会输出任何值,如下图所示:

         添加 fflush() 函数后,结果如下图所示。可以发现,控制台将缓冲区的所有内容进行了输出。

void TestFflush(){

  FILE *file = fopen("CMakeLists.txt", "r");

  if(file){

    char buf[8192];
    setvbuf(file, buf, _IOFBF, 8192);

    puts("Open successfully");

    int err = ferror(file);   // 文件读取是否出错
    int eof = feof(file);     // 文件读取是否结束

    printf("err: %d\n", err);   // 0,说明没有出错
    printf("eof: %d\n", eof);   // 0,说明没有结束

    fflush(stdout); // 清空缓冲区

    fclose(file); // 文件打开后,必须关闭
  }else{
    perror("fopen");          // 打印自带的提示错误信息
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值