在UNIX系统中,标准I/O库最终都要调用文件I/O(read、write等)。每个标准I/O流都有一个与其相关联的文件描述符,可以对一个流调用fileno函数以获得其描述符。

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

  1. #include <stdio.h>
  2. int fileno( FILE *fp );
  3. 返回值:与该流相关联的文件描述符

如果要调用dup或fcntl等函数,则需要此函数。

为了了解你所使用的系统中标准I/O库的实现,最好从头文件<stdio.h>开始。从中可以看到:FILE对象是如何定义的、每个流标志的定义以及定义为宏的各个标准I/O例程(例如getc)。

程序清单5-3中的程序为三个标准流以及一个普通文件相关联的流打印有关缓冲的状态信息。

程序清单5-3 对各个标准I/O流打印缓冲状态信息

  1. [root@localhost apue]# cat prog5-.c
  2. #include "apue.h"
  3.  
  4. void pr_stdio( const char *, FILE * );
  5.  
  6. int
  7. main( void )
  8. {
  9. FILE *fp;
  10. fputs( "enter any character\n", stdout );
  11. if( getchar() == EOF )
  12. err_sys( "getchar error" );
  13. fputs( "one line to standard error\n", stderr );
  14.  
  15. pr_stdio( "stdin", stdin );
  16. pr_stdio( "stdout", stdout );
  17. pr_stdio( "stderr", stderr );
  18.  
  19. if(( fp = fopen("/etc/mtab", "r")) == NULL)
  20. err_sys("fopen error");
  21. if(getc(fp) == EOF)
  22. err_sys("getc error");
  23. pr_stdio("/etc/mtab", fp);
  24. exit();
  25. }
  26.  
  27. void
  28. pr_stdio(const char *name, FILE *fp)
  29. {
  30. printf("stream = %s, ", name);
  31. /*
  32. * The following is nonportable.
  33. */
  34. if(fp->_IO_file_flags & _IO_UNBUFFERED)
  35. printf("unbuffered");
  36. else if(fp->_IO_file_flags & _IO_LINE_BUF)
  37. printf("line buffered");
  38. else /* if neither of above */
  39. printf("fully buffered");
  40. printf(", buffer size = %d\n", fp->_IO_buf_end - fp->_IO_buf_base);
  41. }

注意,在打印缓冲状态信息之前,先对每个流执行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库实现。

如果运行程序清单5-3中的程序两次,一次使三个标准流与终端相连接,另一次使它们重定向到普通文件,则所得结果是:

  1. [root@localhost apue]# ./prog5- stdinstdoutstderr都连至终端
  2. enter any character
  3. 键入换行符
  4. one line to standard error
  5. stream = stdin, line buffered, buffer size =
  6. stream = stdout, line buffered, buffer size =
  7. stream = stderr, unbuffered, buffer size =
  8. stream = /etc/mtab, fully buffered, buffer size =
  9. [root@localhost apue]# ./prog5- < /etc/termcap > std.out > std.err
  10. 三个流都重定向,再次运行该程序
  11. [root@localhost apue]# cat std.err
  12. one line to standard error
  13. [root@localhost apue]# cat std.out
  14. enter any character
  15. stream = stdin, fully buffered, buffer size =
  16. stream = stdout, fully buffered, buffer size =
  17. stream = stderr, unbuffered, buffer size =
  18. stream = /etc/mtab, fully buffered, buffer size =

从中可见,该系统的默认情况是:当标准输入、输出连至终端时,它们是行缓冲的。行缓冲的长度是4096字节。注意,这并没有将输入、输出的行长限制为4096字节,这只是缓冲区的长度。如果要将8192字节的行写到标准输出,则要进行两次write系统调用。当将这两个流重定向到普通文件时,它们就变成是全缓冲的,其缓冲区长度是该文件系统优先选用的I/O长度(从stat结构中得到的st_blksize值)。从中也可看到,标准出错如它所应该的那样是非缓冲的,而普通文件按系统默认是全缓冲的。

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

标准I/O之实现细节的更多相关文章

  1. Python 标准库 urllib2 的使用细节

    刚好用到,这篇文章写得不错,转过来收藏.    转载自 道可道 | Python 标准库 urllib2 的使用细节 Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节 ...

  2. 道可叨 | Python 标准库 urllib2 的使用细节

    道可叨 | Python 标准库 urllib2 的使用细节 request = urllib2.Request(uri) request.add_header('User-Agent', 'fake ...

  3. Python 标准库 urllib2 的使用细节[转]

    转自[http://zhuoqiang.me/python-urllib2-usage.html] Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比 ...

  4. Python 标准库 urllib2 的使用细节(转)

    http://www.cnblogs.com/yuxc/archive/2011/08/01/2123995.html http://blog.csdn.net/wklken/article/deta ...

  5. 转Python 标准库 urllib2 的使用细节

    Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库.这里总结了一些 urllib2 库的使用细节. 1 P ...

  6. 【Python】Python 标准库 urllib2 的使用细节

    转自:http://zhuoqiang.me/python-urllib2-usage.html http://www.cnblogs.com/txw1958/archive/2012/03/12/2 ...

  7. 文件IO函数和标准IO库的区别

    摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lsee ...

  8. 不带缓存的I/O和标准(带缓存的)I/O

    首先,先稍微了解系统调用的概念:       系统调用,英文名system call,每个操作系统都在内核里有一些内建的函数库,这些函数可以用来完成一些系统系统调用把应用程序的请求传给内核,调用相应的 ...

  9. 标准IO与文件IO 的区别【转】

    本文转载自:http://blog.sina.com.cn/s/blog_63f31f3401013jrn.html 先来了解下什么是标准IO以及文件IO. 标准IO:标准I/O是ANSI C建立的一 ...

随机推荐

  1. SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-002-AOP术语解析

    一. 1.Advice Advice是切面的要做的操作,它定义了what.when(什么时候要做什么事) aspects have a purpose—a job they’re meant to d ...

  2. Altium Designer学习:PCB只看当前层

    1 Shift+S          这个快捷键能高亮当前层,并且使其他层变成灰色,见下图:       2 隐藏指定层 在图中右下角的地方,右键,会弹出一个选项条,选择Hide Layers,可以选 ...

  3. URAL1017. Staircases

    链接 简单递推 #include <iostream> #include<cstdio> #include<cstring> #include<algorit ...

  4. bzoj2259

    这道题很不错,首先读入方式有一种跳跃的既视感:读入Si之后,我们可以直接往后跳Si,可以想到最短路,设序列为a[],我们设n+1是终点如果i+a[i]<=n+1 那么i-->i+a[i] ...

  5. Android Paint和Color类

    要绘图,首先得调整画笔,待画笔调整好之后,再将图像绘制到画布上,这样才可以显示在手机屏幕上.Android 中的画笔是 Paint类,Paint 中包含了很多方法对其属性进行设置,主要方法如下: se ...

  6. MEF学习小结 z

    1.什么是MEF. MEF,全称是Managed Extensibility Framework.它是.NET Framework4.0的一个类库,其主要目的是为了创建可扩展的应用程序.按照官方说法就 ...

  7. 关注LoadRunner脚本回放日志中的Warning信息-转载

    关注LoadRunner脚本回放日志中的Warning信息   最近在与大家的讨论中发现了LoadRunner的很多问题,出于解决问题的出发点,我也就相关自己不理解的问题在Google中搜索了一番,并 ...

  8. localStorage保存账号密码

    首先是判断浏览器是否支持这一属性,他是HTML5里的属性: if(window.localStorage){ alert('支持');}else{ alert('不支持');} localStorag ...

  9. 【原】Spark不同运行模式下资源分配源码解读

    版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Task的提交源码解读 http://www.cnblogs.com/yourarebest/p/5423906.html Sch ...

  10. 【HTML】Advanced6:HTML5 Forms Pt. 1: Input Types

    1.Not yet work fully on all major browsers 2.<input type="search tel url email datetime date ...