本文主要介绍C/C的全缓冲、行缓冲、无缓冲的知识,帮助大家更好的理解和学习C/C,有兴趣的朋友可以了解一下。
1.简介
在C/C中,基于I/O流的操作最终会调用系统接口read()和write()来完成I/O操作。为了使程序高效运行,流对象通常提供缓冲区来减少对系统I/O接口的调用次数。
有三种缓冲方式,即:
(1)全缓冲。或者输入和输出缓冲区已满,将执行实际的I/O操作。其他情况,如强制刷新和进程终止,也会执行实际的I/O操作。
对于读操作,当读入内容的字节数等于缓冲区大小或者文件已经到达末尾,或者强制刷新时,会执行实际的I/O操作,将外部文件的内容读入缓冲区;对于写操作,当缓冲区被填满或强制刷新时,将执行实际的I/O操作,并将缓冲区的内容写入外部存储文件。磁盘操作通常是完全缓冲的。
(2)行缓冲。或者输入输出缓冲区在遇到换行符时会执行实际的I/O操作。与其他满缓冲区相同。
(3)无缓冲。如果没有缓冲区,数据将被立即读入内存或输出到外部文件和设备。标准的错误输出stderr是无缓冲的,可以保证错误信息及时反馈给用户,以便用户消除错误。
头文件stdio.h中定义了三种缓冲区类型的宏.
缓冲类型
宏伟的
全隔离
_IOFBF
行缓冲区
_IOLBF
无缓冲
_IONBF
在Linux环境下,下面的代码可以很好的体现全缓冲和行缓冲的区别。
#包含stdio.h
#包含stdlib.h
int glob=6;
int main(int argc,char** argv)
{
int var
pid _ t pid
printf('写入标准输出\ n ');
if(pid=fork()0)
{
printf(“分叉错误”);
}
其他
{
如果(pid==0)
{
glob
var
}
其他
{
睡眠(2);
}
}
printf('pid=%d,glob=%d,var=%d\n ',getpid(),glob,var);
退出(0);
}
编译成功后默认生成A.out,运行结果如下:/a.out
写入标准输出
pid=4823,glob=7,var=4195873
pid=4824,glob=7,var=4195873。/a.out温度. txt
卡特彼勒温度
写入标准输出
pid=4864,glob=7,var=4195873
写入标准输出
pid=4865,glob=7,var=4195873
可以看出,printf输出到标准输出(显示)时是一个行缓冲区。当遇到换行符时,它会将缓冲区的内容输出到显示器,并清空缓冲区。当使用redirect命令时,标准输出被重定向到磁盘文件。此时,标准输出变为完全缓冲。当遇到换行符时,它不会被输出,而是被复制到子进程中。父子流程结束后,每个流程都会有一个输出。
2.缓冲区的设置
(1)函数setbuf()或setbuffer()可用于打开或关闭缓冲区。参数buf指向缓冲区,表示缓冲区开启,通常是满缓冲区。将buf参数设置为NULL表示缓冲已关闭。注意setbuffer()是非C标准库函数,在Linux中很常见。
setbuf()的缓冲区长度至少为BUFSIZ(在stdio.h中定义),否则可能会发生缓冲区溢出。Setbuffer可以指定缓冲区大小。
//@header:stdio.h
//@brief:设置指定的缓冲区或关闭缓冲区。
//@param:stream:文件指针;缓冲区:缓冲区地址
//@注意:使用默认的缓冲区大小BUFSIZ(在stdio.h中定义)
void setbuf ( FILE * stream,char * buffer);
//@注意:和setbuf一样,但是可以指定缓冲区大小。
void setbuffer(FILE *stream,char *buf,size _ t size);
将缓冲区指定为NULL以关闭标准输出缓冲区。
setbuf(标准输出,空)
指定的缓冲区。
静态char new buffer[BUFSIZ];//至少BUFSIZ(在stdio.h中定义),否则可能会有缓冲区溢出。
setbuf(stdout,(char *)new buffer);
//或者指定缓冲区大小
静态字符new buffer[512];
setbuffer(stdout,(char*)newBuffer,512);
(2)要改变缓冲模式,可以使用函数setvbuf()。
//@header:stdio.h
//@brief:更改缓冲模式并设置缓冲
//@param:stream:文件指针;缓冲区缓冲地址;类型:缓冲模式;大小:缓冲区大小
//@ret:0成功,不是0失败。
int setvbuf(FILE *stream,char *buf,int type,unsigned size);
例如,当流缓冲区设置为行缓冲区时,调用setvbuf()时,缓冲区地址设置为NULL,缓冲区大小设置为0。注意,前提是有缓冲。
setvbuf(stream,NULL,_IOLBF,0);//将缓冲区更改为行缓冲区
//上面的代码相当于
setlinebuf(流);//对于Linux
如果对setvbuf的调用指定缓冲区大小大于0,且buffer buf为NULL,则提交给setvbuf for malloc应用程序缓冲区。
//间接申请1024字节的满缓冲区
setvbuf(stream,NULL,_IOFBF,1024);
以上是C/C的全缓冲、行缓冲、无缓冲的细节,更多关于C/C缓冲的信息,请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。