一、介绍
// stdio 库函数
当操作磁盘文件时,缓冲大块数据以减少系统调用,C语言库函数I/O函数fprintf,fscanf(),fgets(),fputs(),fputc(),fgetc()等都是这么做的,stdio库函数可以使编程者免于自行处理对数据的缓冲。运行在用户空间!,下一篇说到运行在内核空间
二、接口定义
// 下列函数都是设置stdio流的缓冲模式
#include <stdio.h>
// 一般使用这个函数,可以设置参数替代下面的3个函数
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
参数:
stream : fopen 打开的流句柄
buf,size: 如果不为空,那么其指向buf区域size大小的内存块作为流的缓冲区
所以应该是动态或者静态分配的一块空间
如果为空,stdio库会为stream自动分配一个缓冲区,就好像我们程序中
并没有执行这个系统调用,为什么会有行缓冲区
mode:
#define _IOFBF 0 /* Fully buffered. */
#define _IOLBF 1 /* Line buffered. */
#define _IONBF 2 /* No buffering. */
_IONBF // 不对I/O进行缓冲,
忽略buf和size参数,可以指定NULL,0.stderr就是这类能立刻输出错误
_IOLBF // 行缓冲I/O,
终端设备的流默认属于这一类,程序输出如printf输出到stdout 默认是行缓冲
_IOFBF // 全缓冲I/O,
就是buf,size结合,读或者写必须达到指定的大小时候才进行输入输出
//相当于是 setvbuf(FILE *stream,buf,(buf!=NULL)? _IOFBF:_IONBF,BUFSIZ)
// BUFSIZ是多大?
/*
#define _G_BUFSIZ 8192 //8K
#define _IO_BUFSIZ _G_BUFSIZ
#ifndef BUFSIZ
# define BUFSIZ _IO_BUFSIZ
#endif
*/
void setbuf(FILE *stream, char *buf);
//相当于是 setvbuf(FILE *stream,buf,(buf!=NULL)? _IOFBF:_IONBF,size)
//就是可以指定size多大,而不是 BUFSIZ 大小
void setbuffer(FILE *stream, char *buf, size_t size);
// 设置行缓冲,相当于是 setvbuf(FILE *stream,NULL,_IOLBF,BUFSIZ)
void setlinebuf(FILE *stream);
// 无论当前采用何种缓冲区模式,任何时候都可以使用fflush库函数强制
// 将stdio输出流中的数据刷新到内核缓冲区中
int fflush(FILE *stream);
参数:
stream: fopen打开的流句柄,若为空,将刷新所有的stdio缓冲区
glibc中的C库函数实现中,若stdin和stdout指向同一终端,
那么无论何时从stdin中读取输入时,都隐含调用了一次fflush()
返回值:
成功返回0,错误返回EOF(-1)并设置errno
三、实例
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
char buf[512];
int main(int argc, char *argv[])
{
int ret;
// 不设置stdout 缓存模式时候,默认是
// 行缓存,行缓存就是一行buf满了或者
// 遇到换行符才输出,
// 下面这个没有换行符,不会立刻输出
printf("this is main func ");
sleep(2); // sleep是为了更方便的看到上面现象
printf("\n");// 这个时候才输出
#if 1
// 设置没有缓冲模式
ret = setvbuf(stdout,NULL,_IONBF,0);
if(ret !=0)
printf("setvbuf error \n");
else
printf("this is main func "); // 立刻输出但是不会换行
//#else
sleep(2);
// 指定缓冲buf,并设置size
memset(buf,0,sizeof(buf));
ret = setvbuf(stdout,buf,_IOFBF,512);
if(ret !=0)
printf("setvbuf error \n");
else
{
printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); //首先9个字符A,不会输出,没满10个
sleep(2);
printf("B");
}
#endif
// test fflush
#if 0
sleep(2);
fflush(stdout); // 调用会显示上面的AB
#endif
sleep(5); // 到这里为止都没有打印上面的AB
return 0; // 直到main结束,隐含调用了fflush
}
来源:CSDN
作者:HarkerYX
链接:https://blog.csdn.net/yexiangCSDN/article/details/103509393