APUE读书笔记3-文件I/O
本文最后更新于:2021年6月20日 下午
本章主要介绍UNIX系统提供的基本I/O函数,并通过文件I/O和open
函数介绍原子操作的概念,最后介绍内核在多进程间共享打开文件信息的数据结构
文件描述符
- 文件描述符:一个非负整数。内核使用文件描述符引用打开的文件。按照惯例,UNIX系统shell将文件描述符0与标准输入相关联,文件描述符1与标准输出相关联,文件描述符2与标准错误相关联。
- POSIX中使用符号常量STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO来代替幻数0、1、2,以此提高程序的可读性。这些常量定义在<unistd.h>中。
- 文件描述符的变化范围是0~OPEN_MAX-1。
函数open和opeat
调用open
或openat
函数可以打开或创建一个文件。
1 |
|
参数:
path:要打开或创建文件的名字
oflag:用来说明此函数的多个选项,用下列一个或多个常量进行“或”运算构成oflag参数
- O_RDONLY:只读打开
- O_WRONLY:只写打开
- O_RDWR:读、写打开
- O_EXEC:只执行打开
- O_SEARCH:只搜索打开(应用于目录)。本书设计的操作系统都不支持该常量
在上面5个常量中必须指定且只能指定一个。下面的常量是可选的:
- O_APPEND:每次写时追加到文件尾端
- O_CLOEXEC:将FD_CLOEXEC常量设置为文件描述符标志
- O_CREAT:若此文件不存在则创建它。使用此选项时,
open
函数需同时说明第3个参数mode(指定新文件的访问权限位) - O_DIRECTORY:如果path引用的不是目录,则出错
- O_EXCL:如果同时指定了O_CREAT时,而文件存在则出错。使用此常量可以测试一个文件是否存在,如果不存在,则创建此文件。这使得测试和创建文件成为一个原子操作
- O_NOCTTY:如果path引用的是终端设备,则不将该设备分配作为此进程的控制终端
- O_NOFOLLOW:如果path引用的是一个符号链接,则出错
- O_NONBLOCK:如果path引用的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选项将文件的本次打开和后续的I/O操作设置为非阻塞方式
- O_SYNC:使每次
write
等待物理I/O操作完成,包括write
操作引起的文件属性更新引起的I/O - O_TRUNC:如果此文件存在,而且为只写或读-写成功打开,则将其长度截断为0
- O_DSYNC:使每次
write
要等待物理I/O操作完成,但是如果该写操作并不影响刚写入的数据,则不需等待文件属性被更新 - O_RSYNC:使每一个以文件描述符作为参数进行的
read
操作等待,直到所有对文件同一部分挂起的写操作都完成
返回值:
- 成功:返回文件描述符
- 出错:返回-1
由open
和openat
函数返回的文件描述符一定是最小的未用描述符数值。fd参数参数将open
和openat
函数区分开,共有3种可能性:
- path参数指定的是绝对路径名,在这种情况下,fd参数被忽略,
openat
函数相当于open
函数 - path参数指定的是相对路径名,fd参数指出了相对路径名在文件系统中的开始地址。fd参数是通过相对路径名所在的目录来获取。
- path参数指定了相对路径名,fd参数具有特殊值AT_FDCWD。在这种情况下,路径名从当前工作目录中获取,
openat
函数在操作上与open
函数类似
openat
函数是POSIX最新版本中增加的函数之一,它能够解决以下两个问题:
- 让线程可以使用相对路径名打开目录中的文件,而不再只能打开当前工作目录
- 避免TOCTTOU(time-of-check-to-time-of-use)错误:如果两个基于文件的函数调用,其中第二个调用依赖于第一个调用的结果,那么这两个调用不是原子操作。这是因为两个函数调用之间文件可能改变,而这造成第一个调用的结果不再有效。
函数creat
APUE读书笔记3-文件I/O
http://yoursite.com/2021/06/06/APUE读书笔记3-文件I-O/