为什么有时候写入文件没有内容?终端上printf打印出来的东西是不是看不到的?这一切背后有什么早已为人所知的秘密?今天我们来谈谈缓冲。也许你听说过三种缓冲模式,但今天我要谈的不止于此。缓冲为了减少读写调用的次数,标准IO库提供了缓冲。可能有人会问,为什么要减少调用次数呢?显然read和write是系统调用,会比较耗时。本文不展开描述。那么缓冲的三种类型是什么?全缓冲在全缓冲的情况下,实际的I/O操作是在标准I/O缓冲区被填满之后执行的。写入磁盘文件通常是完全缓冲的。例如:#include#includeintmain(void){/*以可读可写方式打开*/FILE*fp=fopen("./test.txt","w+");if(NULL==fp){perror("openfilefailed");return-1;}/*写入内容*/charbuf[]="wechat:手网线生\n";fwrite(buf,sizeof(char),sizeof(buf),fp);//fflush(fp);/*sleep一段时间,以便观察*/sleep(20);fclose(fp);return0;}打开一个文件,写入一段字符串.我们编译运行:$gcc-obuffbuff.c$cattest.txtwechat:shouwangxiansheng$./buff这时候观察test.txt:$cattest.txt发现它的内容是空的!已经写到为什么什么都没有了?原因是默认是fullybuffered,所以内容写入文件后,并不直接存在于文件中。当程序关闭文件或程序运行后退出时,再次查看:发现文件已经有内容。除了等待程序运行完毕,还可以使用fflush函数,可以将缓冲区的内容写入磁盘(终端驱动设备表示缓冲区中的数据被丢弃)。所以去掉fwrite下面这一行的注释后,可以发现写入后,可以直接看到文件中的内容。所以当你正在写一个文件,但是查看文件并没有显示任何写入的内容时,不要一直怀疑你的代码。行缓冲行缓冲是指当遇到换行符,或者缓冲区已满(一般为1024字节)时,标准I/O库执行I/O操作。再举个例子:#include#includeintmain(void){printf("wechat:shouwangxiansheng");sleep(10);return0;}编译运行上面的程序:$gcc-olineBufflineBuff.c$./lineBuff你会发现printf执行后,内容并不是马上输出到终端,而是程序运行完毕后输出。你是聪明人,当然你也知道,打印完如果想直接输出到终端,只需要改成下面这样:printf("wechat:shouwangxiansheng\n");不用缓冲,从字面上就可以理解它的意思。再举个例子:noBuff.c*/#include#includeintmain(void){fprintf(stderr,"wechat:shouwangxiansheng");sleep(10);return0;}编译并运行你会发现,运行fprintf语句后,内容直接在终端输出,无需等待换行符。通常,标准错误是无缓冲的。小结通过上面的一些例子,我们还发现了以下规律:通常磁盘上的文件是全缓冲标准输入,标准输入通常是行缓冲的,指向终端设备的流通常是行缓冲的,而指向文件时,为了尽可能多地显示错误消息,它被完全缓冲,标准错误不被缓冲