第十章 系统级别
10.1 Unix I/O
:所有的I/O设备,如网络,磁盘和终端都被模型化为文件,而所有的输入和输出都被当做对应文件的读和写来执行
打开文件 改变当前的文件位置 读写文件 关闭文件
10.2 打开和关闭文件
进程是通过调用open函数来打开一个已经存在的文件或者创建一个新文件的
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int open(char *filename,int flags, mode_t mode);
open函数将filename转化为一个文件描述符,并且返回描述符数字。 返回的描述符总是在进程中当前没有打开的描述符。
flag参数指明了进程打算如何访问这个文件:
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写。
flag参数也可以是一个或更多位掩码的或
O_CREAT:如果文件不存在,就创建它的一个截断的文件
O_TRUNC:如果文件已经存在,就截断它
O_APPEND:在每次写操作前,设置文件位置到文件的结尾处。
mode参数指定了新文件的访问权限位。
10.3 读和写文件
应用程序是通过分别调用read和write函数来执行输入和输出的
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t n);
ssize_t write(int fd, const void *buf,size_t n);
read函数从描述符为fd的当前位置文件拷贝最多n个字节到存储器位置buf,返回值-1表示一个错误,而返回值0表示EOF,否则返回值表示的是实际传送的字节数量。
在某些情况下,read和write传送的字节比应用程序要求的要少。这些不足值不表示有错误,出现这些情况的原因如下:
读时遇到EOF
从终端读文本行
读和写网络套接字
10.4 用RIO包健壮地读写 一个I/O包,称为RIO包,它会自动为你处理上文中所述的不足值。RIO包提供了方便,健壮和高效的I/O。RIO提供了两种不同的函数:
无缓冲的输入输出函数
带缓冲的输入函数
10.5 读取文件元数据
应用程序能够通过调用stat和fstat函数,检索到关于文件的信息。(有时候也称为文件的元数据)
stat函数以一个文件名作为输入
fstat函数是相似的,只不过是以文件描述符而不是文件名作为输入。
10.6 共享文件
描述符表:每个进程都有它独立的描述符表,它的表项是由进程打开的文件描述符来索引的,每个打开的描述符表项指向文件表中的一个表项。
文件表:打开文件的集合是由一张文件表来表示的,所有的进程共享这张表。每个文件表的表项组成包括有当前的文件位置,引用计数,以及一个指向v-node表中对应表项的指针。关闭一个描述符会减少相应的文件表表项中的引用计数。内核不会删除这个文件表表项,直到它的引用计数为零。
v-node表:同文件表一样,所有的进程共享这张v-node表。每个表项包含stat结构中的大多数信息,包括stmode和stsize成员。
10.7 I/O重定向
Unix外壳提供了I/O用户重定向操作符,允许用户将磁盘文件和标准输入联系起来。
10.8 标准I/O
ANSI C定义了一组高级输入输出函数,称为标准I/O库,为程序员提供了Unix I/O的较高级别的替代。
标准I/O库将一个打开的文件模型化为一个流。一个流就是一个指向FILE类型的结构的指针。
实验楼: 课本实验已经在虚拟机上运行。
参考:深入理解计算机系统第十章