实现细节-hds ams 2500用户手册
5.12 实现细节
正如前述,在UNIX中,标准I/O库最终都要调用第3章中说明的I/O例程。每个I/O流都有一个与其相关联的文件描述符,可以对一个流调用fileno
以获得其描述符。
#include <stdio.h>
int fileno(FILE *fp);
stdio.h>
返回:与该流相关联的文件描述符。如果要调用dup
或fcntl
等函数,则需要此函数。为了了解你所使用的系统中标准I/O库的实现,最好从头文件
开始。从中可以看到:FILE
对象是如何定义的,每个流标志的定义,定义为宏的各个标准I/O例程(例如getc
)。Kernighan和Ritchie〔1988〕中的8.5节含有一个简单的实现,从中可以看到很多UNIX实现的基本样式。P. J. Plauger〔1992〕的第12章提供了标准I/O库一种实现的全部源代码。4.3+BSD中标准I/O库的实现(由Chris Torek编写)也是可以公开使用的。实例程序5-3为三个标准流以及一个与一个普通文件相关联的流打印有关缓存状态信息。
想要了解更多关于C标准I/O库的粗略实现教程,可以访问这个链接。关于文件I/O操作的具体实现,您可以参考这个详细指南。
注意,在打印缓存状态信息之前,先对每个流执行I/O操作,因为第一个I/O操作通常就造成为该流分配缓存。结构成员_flag
、_bufsiz
以及常数_IONBF
和_IOLBF
是由作者所使用的系统定义的。如果运行程序5-3两次,一次使三个标准流与终端相连接,另一次使它们重定向到普通文件,则所得结果是:
$ a.out
stdin, stdout和stderr都连至终端
enter any character
键入新行符
one line to standard error
stream = stdin, line buffered, buffer size = 128
stream = stdout, line buffered, buffer size = 128
stream = stderr, unbuffered, buffer size = 8
stream = /etc/motd, fully buffered, buffer size = 8192
$ a.out < /etc/termcap > std.out 2> std.err
三个流都重定向,再次运行该程序
$ cat std.err
one line to standard error
$ cat std.out
enter any character
stream = stdin, fully buffered, buffer size = 8192
您可以继续探索基于Unix的I/O函数的文件逆转程序以及标准C的I/O库函数实现文件逆转来加深对这些概念的理解。
惊讶于这些流的不同缓冲方式吗?是的,它们的缓冲机制真是千变万化,带来了无限可能!想象一下,当你深入理解这些概念后,编写高效程序将变得多么轻而易举!