Unix 文件IO
文件描述符号
对于内核而言,所有打开的文件通过文件描述符引用,是一个非负整数.
在POSIX1中,在<unistd.h>
中定义了
STDIN_FILENO(0): 标准输入
STDOUT_FILENO(1): 标准输出
STDERR_FILENO(2): 标准错误输出
文件描述符号的范围是{0-OPEN_MAX-1}
函数open和openat
man 2 open
man 2 openat
- pathname: 打开或者是创建文件的名字
flags: 标识,使用下面的常量,多个可以使用
- O_RDONLY 只读打开(0)
- O_WRONLY 只写打开(1)
O_RDWR 读写打开
OS_EXEC 只执行打开
OS_SEARCH 搜索打开(不支持)
以上的这5个常量必须指定一个而且只能指定一个,下面的产量是可选的.
- O_APPEND
- O_CLOEXEC 把
FD_CLOEXEC
设置为文件描述符标志 - O_CREAT 若文件不存在,则创建它,此时需要第三个参数(
openat
第四个)mode
,指定权限位以及可以使用进程的umask
修改 - O_DIRECTORY 如果不是一个目录就会出错
- O_EXCL 如果指定了
O_CREAT
并且文件存在则会出错 - O_NOCTTY 如果path引用的是终端设备,则不将该设备分配作为该进程的控制终端.
- O_NOFOLLOW 如果path引用的是符号链接,则出错
- O_NONBLOCK 如果path引用的是一FIFO,一个块特殊文件或者一个字符特殊文件,则此选项为文件的本次打开操作后和后续的I/O操作设置非阻塞方式.
- O_SYNC 使每次write等待物理I/O操作完成
- O_TRUNC 如果此文件存在,而且为只写(或者读写)成功打开,则将其长度截断为0
- O_TTY_INIT 如果打开一个还未打开的终端设备,设置非标准termios参数.
下面两个参数是可选择的 - O_DSYNC
- O_RSYNC
creat
创建一个文件,相当于open(path, O_WRONLY| O_CREAT | O_TRUNC, mode)
close
关闭一个文件,并且释放该进程加在该文件记录上的所有的锁
lseek
每打开一个文件都有一个与其相关联的当前文件偏移量
|
|
read
|
|
read函数需要搞清楚的几个问题在于
返回值
- 返回读取到的字节数
- 若到了文件末尾,返回0
- 出错,返回-1
write
返回值
- 返回写的字节数
- 出错,返回-1
I/O的效率
在linux的ext4文件系统下,磁盘长度为4096字节
read ahead预读技术
文件共享
内核使用3种数据结构标示打开文件
- 1) 每个进程在进程表中都有一个记录项,记录项中包含了一张打开的文件描述符表,每个文件描述符占有一项,与每个文件描速符相关联的是:
- a) 文件状态标志
- b) 指向文件表项的指针
- 2) 内核为所有打开文件维持一张文件表,每个文件表项包含
- a) 文件状态标志(读,写)
- b) 当前文件偏移量
- c) 指向文件v节点的指针
- 3) 每个打开的文件(或设备)都有一个v节点
当两个进程打开同一个文件
fcntl
|
|
fcntl
函数有以下5个功能
- (1) 复制一个已有的描述符(cmd=
F_DUPFD
或F_DUPFD_CLOEXEC
) - (2) 获取/设置文件描述符标志(cmd=
F_GETFE
或F_SETFD
) - (3) 获取/设置文件状态标志(cmd=
F_GETFL
或F_SETFL
) - (4) 获取/设置异步I/O所有权(cmd=
F_GETOWN
或F_SETOWN
) - (5) 获取/设置记录锁(cmd=
F_GETLK
,F_SETLK
或F_SETLWK
)
|
|