20165232《信息安全系统设计基础》第六周学习总结
教材内容总结--系统级I/O
10.1 UnixI/O
- Linux内核引出一个简单,低级的应用接口(Unix I/O),所有的输入和输出都能以一种统一一致的方式执行。
- 输入输出的执行方式
- 打开文件
描述符:内核打开文件时返回的一个小的非负整数
- 每个进程开始时都有三个打开的文件
- 标准输入(描述符为0)
- 标准输出(描述符为1)
- 标准错误(描述符为2)
- 改变当前的文件位置
对每一个打开的文件,内核保持着一个文件位置k,seek操作能够设置文件的当前位置为k
- 读写文件
- 关闭文件
10.2 文件
- 普通文件中文本文件每一行都是一个字符序列,以\n结束,新行符与ASCII的换行符一样,数字值为0x0a
- 目录:每个目录至少含有两个条目,.是到该目录自身的连接,..是到父目录的链接。
- 套接字:用来与另一个进程进行跨网络通信的文件
- 路径名:是一个字符串,包括一个可选斜杠后跟文件名
- 绝对路径名:在图中hello.c的绝对路径名为/home/droh/hello.c
- 相对路径名:若/home/droh是当前目录,则./hello.c,若/home/bryant是当前目录,则../home/dorh/hello.c
10.3 打开和关闭文件
- open函数:将filename转换为一个文件描述符,并且返回描述符数字。返回的描述符总是在进程中当前没有打开的最小描述符。
- O_RDONLY只读
- O_WEONLY 只写
- O_RDWR 可读可写
- O_CREAT 创建
- O_TRUNC 截断
- O_APPEND设置到结尾
- mode参数:指定了新文件的访问权限位。
10.4 读和写文件
- 应用程序通过调用read和write来执行输入和输出,在某些情况下,read和write传送的字节比应用程序要求的少,出现这样情况的原因有
- 读时遇到EOF。
- 从终端读文本行。
- 读和写网络套接字。
10.5 RIO
- RIO的无缓冲的输入输出函数
#include "csapp.h" ssize_t rio_readn(int fd,void *usrbuf,size_t n); ssize_t rio_writen(int fd,void *usrbuf,size_t n);
- RIO的带缓冲的输入函数
#include "csapp.h" void rio_readinitb(rio_t *rp,int fd); ssize_t rio_readlineb(rio_t *rp,void *usrbuf,size_t maxlen); ssize_t rio_readnb(rio_t *rp,void *usrbuf,size_t n);
- RIO读程序的核心是rio_read函数
- rio_read函数和linux_read函数有同样的语义,出错时返回值-1,并适当的设置errno。在EOF时,返回值0。
10.6 读取文件元数据
- stat函数以一个文件名作为输入,fstat以文件描述符作为输入。
- st_size成员包含了文件的字节数大小,st_mode成员编码了文件访问许可位和文件类型。
10.7 读取目录内容
- 应用程序可以用readdir系列函数读取目录内容
- 每次对readdir的调用反悔的都是指向流dirp中下一个目录的指针。
10.8 共享文件
- 描述符表:每个打开的描述符表项指向文件表中的一个表项。
- 文件表:打开文件的所有的进程共享这张表,包括文件位置、引用计数、一个指向v-node表中对应表项的指针。
- v-node表:所有的进程共享这张v-node表,每个表项包含stat结构中的大多数信息,包括st_mode和st_size成员。
10.9 I/O重定向
linux>ls>foo.txt
将标准输出重定向到磁盘文件foo.txt。
int dup2(int oldfd,int newfd)
复制描述符表项oldfd到描述符表表项newfd,覆盖描述符表项newfd以前的内容。如果newfd已经打开了,dup2会在复制oldfd之前关闭newfd。