File IO
UNIX系统上的大多数文件I/O只能使用5个函数来执行:open、read、write、lseek和close,这些函数通常被称为无缓冲I/O,
1.文件描述符
对于内核,所有打开的文件都由文件描述符引用。文件描述符是非负整数。
- 当我们打开一个现有文件或创建一个新文件时,内核会向进程返回一个文件描述符。
- 当我们想要读或写一个文件时,我们用
open
或create
返回的文件描述符作为参数来标识该文件。
按照惯例,UNIX系统shell将0对应标准输入
STDIN_FILENO
,将1对应标准输出STDOUT_FILENO
,将2对应标准错误输出STDERR_FILENO
。
- 文件描述符的范围从0到
OPEN_MAX−1
。
2.文件IO函数
2.1 open
函数
通过调用
open
函数或openat
函数打开或创建文件。
#include <fcntl.h>
int open(const char *path, int oflag, ... /* mode_t mode */ );
int openat(int fd, const char *path, int oflag, ... /* mode_t mode */ );
Both return: file descriptor if OK, −1 on error
最后一个参数显示为…,这是指定其余参数的数量和类型可能不同。
对于这些函数,最后一个参数仅在创建新文件时使用
path
参数是要打开或创建的文件的名称。这个函数有许多选项,由
oflag
参数指定。这个参数由<fcntl.h>
头文件中的一个或多个常量组成:O_RDONLY Open for reading only. O_WRONLY Open for writing only. O_RDWR Open for reading and writing. O_EXEC Open for execute only.
为了与旧程序兼容,大多数实现将
O_RDONLY
定义为0,O_WRONLY
定义为1,O_RDWR
定义为2。前五个常量中只有一个必须指定。以下常量是可选的:
O_APPEND 在每次写入时附加到文件末尾。 O_CLOEXEC 设置FD_CLOEXEC文件描述符标志。 O_CREAT 如果文件不存在,则创建该文件。 O_DIRECTORY 如果路径没有指向目录,则生成错误。 O_EXCL 如果指定了O_CREAT并且文件已经存在,则生成一个错误。 O_NOFOLLOW 如果路径指向符号链接,则生成错误。 O_NONBLOCK 此选项为打开文件和随后的I/O设置非阻塞模式。 O_TRUNC 如果文件存在,并且成功地以只写或读写的方式打开,则将其长度截断为0。 O_SYNC 让每个写操作等待物理I/O完成,包括更新由于写操作而修改的文件属性所需的I/O。
下面两个标志也是可选的。它们是同步输入和输出选项的一部分
O_DSYNC 让每次写入等待物理I/O完成,但如果文件属性不影响读取刚刚写入的数据的能力,就不要等待文件属性的更新。 O_RSYNC 让文件描述符上的每个读操作都等待,直到文件同一部分的任何挂起的写操作完成。
open
和openat
返回的文件描述符fd
保证是编号最低的未使用描述符。