07-文件IO模型
2.5 文件I/O模型
UNIX系统I/O模型最为显著的特性之一是其I/O通用性概念。也就是说,同一套系统调用(open()、read()、write()、close()等)所执行的I/O操作,可施之于所有文件类型,包括设备文件在内。(应用程序发起的I/O请求,内核会将其转化为相应的文件系统操作,或者设备驱动程序操作,以此来执行针对目标文件或设备的I/O操作。)因此,采用这些系统调用的程序能够处理任何类型的文件。
就本质而言,内核只提供一种文件类型:字节流序列,在处理磁盘文件、磁盘或磁带设备时,可通过lseek()系统调用来随机访问。
许多应用程序和函数库都将新行符(十进制ASCII码为10,有时亦称其为换行)视为文本中一行的结束和另一行的开始。UNIX系统没有文件结束符的概念,读取文件时如无数据返回,便会认定抵达文件末尾。
文件描述符
I/O 系统调用使用文件描述符——(往往是数值很小的)非负整数——来指代打开的文件。获取文件描述符的常用手法是调用 open(),在参数中指定 I/O 操作目标文件的路径名。
通常,由shell启动的进程会继承3个已打开的文件描述符:描述符0为标准输入,指代为进程提供输入的文件;描述符1为标准输出,指代供进程写入输出的文件;描述符2为标准错误,指代供进程写入错误消息或异常通告的文件。在交互式shell或程序中,上述三者一般都指向终端。在stdio函数库中,这几种描述符分别与文件流stdin、stdout和stderr相对应。
stdio函数库
C编程语言在执行文件I/O操作时,往往会调用C语言标准库的I/O函数。也将这样一组I/O函数称为stdio函数库,其中包括fopen()、fclose()、scanf()、printf()、fgets()、fputs()等。stdio函数位于I/O系统调用层(open()、close()、read()、write()等)之上。
本书假定读者已经了解了C语言的标准I/O(stdio)函数,因此也不会介绍这方面的内容。更多与stdio函数库有关的信息请参考[Kernighan & Ritchie, 1988]、[Harbison & Steele,2002]、[Plauger、1992]和[Stevens & Rago, 2005]。