Linux系统函数查看流对象是行缓冲还是全缓冲还是无缓冲

Linux系统函数查看流对象是行缓冲还是全缓冲还是无缓冲

有关全/行/无缓冲的区别
在《UNIX环境高级编程》第三版131页有这么个程序(已化简)

# include <unistd.h>
# include<stdio.h>
# include<error.h>
# include <stdlib.h> 
# include <errno.h> 
# ifdef _IONBF//等同于 #if define(_IONBF)
int is_unbuffered(FILE *fp)
{
   return((fp->_flags)&_IONBF);
}
int is_linebuffed(FILE *fp)
{
   return((fp->_flags)&_IOLBF);
   
}
int buffer_size(FILE *fp)
{
   return (fp->_IO_buf_end-fp->_IO_buf_base);//return buff size
}
#else

#error unknown stdio implementation

#endif

void pr_stdio(const char * name, FILE * fp)
{
   printf("stream=%s ",name);
   if(is_unbuffered(fp))
   {
      printf("unbuffered");
   }
   else if(is_linebuffed(fp))
   {
      printf("line buffered");
   }
   else
   {
      printf("fully buffered");
   }
   printf(", buffer size = %d\n", buffer_size(fp));
}



int main(int argc,char *argv[])
{
   
   fputs("enter any character\n",stdout);
   if(getchar()==EOF)
   {
      printf("get char error\n");
   }
   fputs("one line to standard error\n",stderr);
   pr_stdio("stdin",stdin);
   pr_stdio("stdout",stdout);
   pr_stdio("stderr",stderr);
   return 0;   
}

其原理是利用FILE结构体的flags来判断该IO流是全、行、无缓冲的哪一个。
但是执行结果确是
在这里插入图片描述
这明显是不对的,因为我们都知道,标准输入流(stdin)和标准输出流(stdout)都是行缓冲(这个无可争议,我也试过了,ubuntu20上确实是行缓冲),标准错误是无缓冲,这个是对的。
我们自定义一个文件描述符(默认应该是全缓冲),然后分别用setlinebuf()和setvbuf设置其为行缓冲和无缓冲,然后在debug模式观察flags标识位

   FILE * stc=fopen("log.txt","a");
   
   pr_stdio("stc",stc);//全缓冲
   
   setlinebuf(stc);
   pr_stdio("stc",stc);//行缓冲
   
   char *buf;
   setvbuf(stc,buf,_IONBF,4096);
   pr_stdio("stc",stc);//无缓冲

运行结果为
在这里插入图片描述
全缓冲结构体数据
在这里插入图片描述行缓冲结构体数据
在这里插入图片描述无缓冲结构体数据
在这里插入图片描述
转化为二进制比较
在这里插入图片描述在这里插入图片描述在这里插入图片描述一个0x484(全缓冲),一个0x684(行缓冲),一个0x487(无缓冲),我们对上述进行分析,然后重新写判断函数,经过我们分析了stdout,stderr的flags位后,发现,如果是行缓冲,需要0x200,如果是无缓冲,需要0x1
修改判断函数如下:

int is_unbuffered(FILE *fp)//判断是否无缓冲
{
   return((fp->_flags)&0x1);
}
int is_linebuffed(FILE *fp)//判断是否行缓冲
{
   return((fp->_flags)&0x200);
}

最终程序如下:

# include <unistd.h>
# include<stdio.h>
# include<error.h>
# include <stdlib.h> 
# include <errno.h> 
# ifdef _IONBF
int is_unbuffered(FILE *fp)
{
   return((fp->_flags)&0x1);
}
int is_linebuffed(FILE *fp)
{
   return((fp->_flags)&0x200);
   
}

int buffer_size(FILE *fp)
{
   return (fp->_IO_buf_end-fp->_IO_buf_base);//return buff size
}
#else

#error unknown stdio implementation

#endif

void pr_stdio(const char * name, FILE * fp)
{
   printf("stream=%s ",name);
   if(is_unbuffered(fp))
   {
      printf("unbuffered");
   }
   else if(is_linebuffed(fp))
   {
      printf("line buffered");
   }
   else
   {
      printf("fully buffered");
   }
   printf(", buffer size = %d\n", buffer_size(fp));
}



int main(int argc,char *argv[])
{
   
   fputs("enter any character\n",stdout);
   if(getchar()==EOF)
   {
      printf("get char error\n");
   }
   
   fputs("one line to standard error\n",stderr);
   
   FILE * stc=fopen("log.txt","a");
   pr_stdio("stc",stc);
   char *buf;
   setlinebuf(stc);
   //setvbuf(stc,buf,_IONBF,4096);
   pr_stdio("stc",stc);
   
   setvbuf(stc,buf,_IONBF,4096);
   pr_stdio("stc",stc);

   pr_stdio("stdin",stdin);
   pr_stdio("stdout",stdout);
   pr_stdio("stderr",stderr);
   return 0;   
   
}

执行结果:
在这里插入图片描述符合要求

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值