标准IO的缓冲区你了解多少?C语言小白一定要掌握

有些刚接触C语言的同学可能会遇到以下这种情况:“printf()一直打印不出东西出来,直到某一刻却输出来一大堆东西,然后回头加上'\n'之后又可以正常输出了。”这是为什么呢?这就是标准IO的缓冲区在作怪,printf()是行缓冲的,也就是说只有遇到'\n'才会马上把内容刷出来,否则只能等到程序退出或者标准IO缓冲区满了才会把内容刷出来。


标准IO缓冲区

如下图所示,每当使用标准IO的写操作函数,试图将数据写入文件 a.txt 时,数据都会流过缓冲区(一般大小为1024字节),然后再在适当的时刻冲洗(或称刷新,flush)到内核,最后才真正写入设备文件。



按照缓冲区按照什么时候冲洗数据到内核,可以将缓冲区分成以下三类:

  • 不缓冲类型:
    • 一旦有数据,立刻将数据冲洗到文件(立即在存储器中更新文件)
  • 全缓冲类型:
    • 一旦填满缓冲区,立刻将数据冲洗到文件
    • 程序正常退出时,立刻将数据冲洗到文件
    • 遇到 fflush() 强制冲洗时,立刻将数据冲洗到文件
    • 关闭文件时,立刻将数据冲洗到文件
    • 读取文件内容时,立刻将数据冲洗到文件
    • 改变缓冲区类型时,立刻将数据冲洗到文件
  • 行缓冲类型:
    • 同全缓冲类型
    • 一旦遇到’\n’时,立刻将数据冲洗到文件

关键点:

  1. 缓冲(buffer)都是针对写操作而言的,缓冲的存在是为了提高写效率(数据量比较大的情况下)。
  2. 对于标准输出而言,默认是行缓冲的
  3. 对于标准出错而言,默认是不缓冲的;
  4. 对于普通文件而言,默认都是全缓冲类型
  5. 滞留在缓冲区中的数据有时被称为脏数据(dirty data),脏数据的存在代表程序操作的结果与文件真实状态不一致,若未正常冲洗这些脏数据就退出程序则有可能会造成数据丢失
  6. 这三种缓冲类型,可以通过函数 setbuf()/setvbuf() 来修改。

setbuf():

setvbuf():


经过好几节的分享,终于把系统IO和标准IO的知识点给大家整理了一遍。

前面几节的内容:
要对文件操作,用系统IO还是标准IO?不清楚的小白请进来学习

标准IO的函数接口,你了解多少?十分钟、一篇文章就能捋清楚

系统IO常用的API接口,你认识多少个?会用多少个?新手一定要看


度白嵌入式,持续分享通俗易懂的嵌入式知识。欢迎志同道合的朋友关注交流~

原文链接:,转发请注明来源!