Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5512639
  • 博文数量: 922
  • 博客积分: 19333
  • 博客等级: 上将
  • 技术积分: 11226
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 14:33
文章分类

全部博文(922)

文章存档

2023年(1)

2020年(2)

2019年(1)

2017年(1)

2016年(3)

2015年(10)

2014年(17)

2013年(49)

2012年(291)

2011年(266)

2010年(95)

2009年(54)

2008年(132)

分类: LINUX

2012-01-04 21:16:03

++++++APUE读书笔记-05标准输入输出库(7)++++++
 
12、实现细节
================================================
 每一个标准I/O流都和一个文件描述符号相关联,通过如下函数获得一个标准I/O流的文件描述符号:
 #include
 int fileno(FILE *fp);
 返回:和fp流相关的文件描述符号。
 注意这个函数不是ISO C指定的,而是被做为POSIX.1的扩展指定。
 下面例子打印三种标准流以及一个普通文件的缓存:
 void    pr_stdio(const char *, FILE *);
 int main(void)
 {
  FILE    *fp;
  fputs("enter any character\n", stdout);
  if (getchar() == EOF)
  err_sys("getchar error");/*错误情况,这里可以忽略它。该函数是原书中为了叙述方便实现的,可参考原书附录*/
  fputs("one line to standard error\n", stderr);
  pr_stdio("stdin",  stdin);
  pr_stdio("stdout", stdout);
  pr_stdio("stderr", stderr);
  if ((fp = fopen("/etc/motd", "r")) == NULL)
   err_sys("fopen error");
  if (getc(fp) == EOF)
   err_sys("getc error");
  pr_stdio("/etc/motd", fp);
  exit(0);
 }
 void pr_stdio(const char *name, FILE *fp)
 {
  printf("stream = %s, ", name);
  /*
  * The following is nonportable.
  */
  if (fp->_IO_file_flags & _IO_UNBUFFERED)
   printf("unbuffered");
  else if (fp->_IO_file_flags & _IO_LINE_BUF)
   printf("line buffered");
  else /* if neither of above */
   printf("fully buffered");
  printf(", buffer size = %d\n", fp->_IO_buf_end - fp->_IO_buf_base);
 }
 需要注意的是,我们在打印缓存状态之前对每个流进行了I/O操作,因为第一次的I/O操作会为流分配一个缓存。结构成员_IO_file_flags,IO_buf_base,  以及_IO_buf_end 和常量 _IO_UNBUFFERED 与_IO_LINE_BUFFERED由Linux上面的GNU标准I/O库定义。需要注意其他的UNIX系统可能有不同的标准I/O库实现。
 下面是运行以上程序两次的结果,一次将三个标准流连接到终端,一次将它们重定向到文件:
 $ ./a.out                       stdin, stdout, and stderr connected to terminal
 enter any character
                                    we type a newline
 one line to standard error
 stream = stdin, line buffered, buffer size = 1024
 stream = stdout, line buffered, buffer size = 1024
 stream = stderr, unbuffered, buffer size = 1
 stream = /etc/motd, fully buffered, buffer size = 4096
 $ ./a.out < /etc/termcap > std.out 2> std.err
                                    run it again with all three streams redirected
 $ cat std.err
 one line to standard error
 $ cat std.out
 enter any character
 stream = stdin, fully buffered, buffer size = 4096
 stream = stdout, fully buffered, buffer size = 4096
 stream = stderr, unbuffered, buffer size = 1
 stream = /etc/motd, fully buffered, buffer size = 4096
 由上可知,默认系统当标准输入输出连接到终端上面的时候,其缓存是行缓存。行缓存长度是1024字节。这并不表示我们只能进行1024字节的行输入和输出,那只是一个缓存的大小。所以如果进行了2048字节的行输出将会导致调用两次write系统调用。当我们将这两个流重定向到普通文件的时候,它们是满缓存的,缓存的大小和文件系统I/O时候导致更优时间、stat结构的、st_blksize大小相等。我们也看到,标准错误总是非缓存的(重定向之后也如此),普通文件是满缓存的。
参考:
 
 
阅读(422) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~