Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1814334
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

2012-03-29 12:12:02

正如我们提到过的,在UNIX系统下,标准I/O库最后会调用第3章描述的I/O程序。每个标准I/O流有一个相关的文件描述符,而我们可以调用fileno来得到流的文件描述符。



  1. #include <stdio.h>

  2. int fileno(FILE *fp);

  3. 返回相关联的文件描述符。


注意fileno不是ISO C标准的一部分,而是POSIX.1支持的一个扩展。


例如,如果想调用dup或fcntl函数,我们需要这个函数。


要看你系统上标准I/O库的实现,从头文件开始。这会展示FILE对象是如何定义的,每个流标志的定义,还有任何被定义为宏的I/O函数,比如getc。GNU标准I/O库的实现是公开的。


下面的代码打印三个标准流以及与一个普通文件关联的流的缓冲:



  1. #include <stdio.h>

  2. void pr_stdio(const char *, FILE *);

  3. int
  4. main(void)
  5. {
  6.     FILE *fp;

  7.     fputs("enter any character\n", stdout);
  8.     if (getchar() == EOF)
  9.         exit(1);
  10.     fputs("one line to standard error\n", stderr);

  11.     pr_stdio("stdin", stdin);
  12.     pr_stdio("stdout", stdout);
  13.     pr_stdio("stderr", stderr);

  14.     if ((fp = fopen("/etc/motd", "r")) == NULL)
  15.         exit(1);
  16.     if (getc(fp) == EOF)
  17.         exit(1);
  18.     pr_stdio("/tec/motd", fp);
  19.     exit(0);
  20. }

  21. void
  22. pr_stdio(const char *name, FILE *fp)
  23. {
  24.     printf("stream = %s, ", name);

  25.     /*
  26.      * The following is nonportable.
  27.      */
  28.     if (fp->_IO_file_flags & _IO_UNBUFFERED)
  29.         printf("unbuffered");
  30.     else if (fp->_IO_file_flags & _IO_LINE_BUF)
  31.         printf("line buffered");
  32.     else /* if neither of above */
  33.         printf("fully buffered");
  34.     printf(", buffer size = %d\n", fp->_IO_buf_end - fp->_IO_buf_base);
  35. }

注意我们在打印每个流的缓冲状态前,都为它执行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
enter any character
a
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 = /tec/motd, fully buffered, buffer size = 4096


$ ./a.out std.out 2>std.err
$ 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 = /tec/motd, fully buffered, buffer size = 4096
$ cat std.err
one line to standard error


我们可以看到默认情况下,系统的标准输入和标准输出连接到终端时是行缓冲的。行缓冲有1024字节。注意这并不限制我们输出或输入1024字节的行,那只 是缓冲的大小。向标准输出写一个2048字节的行将会请求两个系统调用。当我们把这两个流重定向到普通文件时,它们变为完全缓冲的了,而缓冲大小与文件系 统的首选I/O尺寸一样--stat结构体里的st_blksize的值。我们也看到标准错误总是无缓冲的,正如它应该的那样。一个普通文件默认为完全缓 冲的。

阅读(971) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~