Unix I/O
文件是一个字节序列。 所有的 IO 设备都视为文件,所有 IO 都以一种统一的方式进行处理。
文件
- 普通文件,包含任意数据
- 目录文件,包含一组链接,每个链接将一个文件名映射到一个文件
- 套接字,用来与另一个进程进行跨网络通信的文件
打开和关闭文件
打开文件
open 函数,若成功返回新文件的描述符,若出错返回 -1
关闭文件
close 函数,若成功则为 0,若出错则为 -1
- 关闭已关闭的文件会返回错误
- 一个进程终止时内核对该进程所有未关闭的文件描述符调用
close - 成功关闭并不确保数据已经保存到磁盘
读写文件
读文件
read 函数,若成功返回读的字节数,若 EOF 返回 0,若出错返回 -1
写文件
write 函数,若成功返回写的字节数,若出错则返回 -1
- 读写过程中返回值比要求的读写字节值少是可能的,不是错误,可能在以下情况发生
- 读到 EOF
- 从终端读入文本行
- 从 socket 读写数据
- 读写不足不会在以下情况发生
- 从磁盘读取(除 EOF)
- 向磁盘写入
读取文件元数据
元数据是关于文件的信息。
stat 函数以文件名为输入,填写一个 stat 结构体。
若成功返回 0,出错返回 -1
读取目录内容
opendir 函数返回指向目录流的指针,若出错则为 NULL
readdir 函数返回指向流中的下一个目录项的指针,若没有更多目录项,返回 NULL
- 每个目录项包含索引节点号和文件名
closedir函数关闭流并释放资源
共享文件
- 描述符表:每个进程独立,每个打开的描述符表项指向文件表中的一个表项
- 文件表:所有进程共享。每个文件表表项包括当前文件位置、引用计数和一个指向 v-node 表中表项的指针
- v-node表:所有进程共享。每个表项包含
stat结构中的大多数信息
多个描述符可以通过不同的文件表表项来引用同一个文件。例如,用相同的文件名 open两次。 子进程继承父进程的描述符表,打开文件表中的引用计数加一。
I/O 重定向
int dup2(int oldfd, int newfd);dup2 函数,复制 oldfd 到 newfd
如果 newfd 已经打开了,则会在复制 oldfd 前关闭 newfd
标准 I/O
标准 I/O 库将一个打开的文件模型化为一个流,即一个指向 FILE 类型的指针,每个 C 程序开始时都有三个打开的流 stdin、stdout、stderr
Unix I/O vs 标准I/O
标准 I/O 和 RIO 都是用 Unix I/O 实现的。
- Unix I/O 开销最小,提供了访问文件元数据的功能,但是对不足值处理不够,容易出错
- 标准 I/O 通过使用缓冲增加了效率,且可以自动处理不足值,但是没有提供访问文件元数据的功能,且不是同步信号安全的
