系统级IO
本章核心:
如何使用IO接口来统一的处理”主存”和”外部设备”的数据转换
为什么要学习Unix I/O?
- 理解其他系统概念:譬如了解I/O和进程(fork)的关系
- 除了 Unix I/O 外 ,别无选择
UNIX I/O
什么是文件
一个Unix文件是一个字节序列,所有的外部IO设备(网络、磁盘、终端)都被映射为文件
什么是Unix I/O?它的定义有什么意义?
Unix I/O是内核提供一系列接口,使得对所有这些设备的访问都是以文件的方式的进行:
- 打开文件:一个应用程序通过要求内核打开相应的文件,内核将返回一个非负整数,称为描述符,记录打开文件的所有信息:标准输入(描述符0)、标准输出(描述符1)、标准错误(描述符2)
- 改变当前文件位置:内核保持一个文件的位置k,初始为0,表示从文件开始处偏移的字节数。通过seek操作。
- 读写文件:读操作就是从文件拷贝n个字节到存储器,如果是从k处开始,就是拷贝k+n为止。文件的大小为m,如果k≥m就会触发(EOF),所有就不需要明确的EOF字符了。写操作就是从存储器拷贝n个字节到文件当前位置k处。
- 关闭文件:内核释放打开文件时创建的数据结构,释放所有的存储器资源。
文件
如何区分文件在系统中的角色?
type:
- 普通文件:可以分为文本文件和二进制文件。文本文件是只含有ASCII或Unicode的普通文件,其余是二进制文件。
- 目录:是包含一组链接的文件
- 套接字:用来与另一个进程进行跨网络通信的文件
文件和进程的关系?
进程上下文中都有一个当前工作目录
打开和关闭文件
打开文件:
- filename:是文件名
- flags:访问方式,O_RDONLY|O_WRONLY|O_RDWR;
- mode:访问权限
关闭文件:
读写文件
读和写文件:
什么是不足值?
有时候传送的字节会比要求的少,实际上的传送字节就是不足值
哪些情况会返回不足值?
- 遇到EOF
- 从终端读文本行,不足值等于输入的文本行
- 读写套接字,网络延迟导致
实际上,除了EOF,当读写取磁盘文件时,将不会遇到不足值,容易出现不足值的情况往往出现在读写网络套接字的时候。
RIO
什么是RIO?有什么用?
Robust健壮的:Unix IO的包装,增强其功能:
- 处理除EOF和Error之外的不足值(通过不足时循环读写)
- 使用缓冲来增强读写性能(通过缓存)
不带缓冲:
带缓冲:
rio_t是一个结构体:
rio_readinitb是初始化:
读取文件的元数据
什么是元数据?
文件元数据是指文件本身的一些信息,包含:访问模式、大小和创建时间:
可以通过以下指令来判断类型:
读取目录内容
共享文件
系统如何记录打开的文件?
- 描述符表:每个独立的进程1张,指向一打开的文件表;
- 文件表:包括打开文件位置,引用数量,以及一个指向元数据的v-node指针;
- v-node表:包含stat结构的大部分信息;
文件是如何被共享的?
如果共享文件位置(读写),则指向同一文件表项
如果只是共享同一文件,则指向不同文件表项,同一“v-node”表项
如何理解fork后的文件共享?
I/O重定向
什么是重定向?
修改描述符表项的指向
如何将磁盘文件和标准输入输出联系起来?
dup2(4,1)
描述符1默认是标准输出,描述符4是其他文件
标准I/O
标准IO是C提供的一套高级输入输出的函数
和RIO、Unix IO的对比
标准I/O是双工,因此在读写转换的时候需要修改文件位置
综合
如何选择I/O包?
尽可能使用标准IO
由于标准IO使用lseek来修改文件位置以实现双工,但是由于lseek对套接字是非法的,所以标准IO无法用于套接字IO