1.文件描述符
对于内核而言,所有打开的文件都是通过文件描述符应用的。文件描述符是一个非负整数。当我们打开或者创建一个文件时,内核向进程返回一个文件描述符来标识该文件。UNIX系统shell把文件描述符0(STDIN_FILENO)与进程标准输入关联,文件描述符1(STDOUT_FILENO)与进程标准输出相关联,文件描述符2(STDERR_FILENO)与标准错误相关联。如果不做特别处理,那么这3个描述符都链接向终端。但可以重定向来改变,例如:
ls > text.txt
这样标准输出重定向到text.txt文件
2.open函数
int open(const char *path,int oflag,mode_t mode);
//第三个参数仅在第二个参数使用O_CREAT时使用,用来指定新文件的访问权限位
path参数是要打开或者创建文件的文件名。
oflag参数有必选且只能选择一个,还有许多可选项,他们用|链接
必选项
O_RDONLY | 只读打开 |
O_WRONLY | 只写打开 |
O_RDWR | 读,写打开 |
O_EXEC | 只执行打开 |
可选项
O_APPEND | 每次写都追加到文件末尾 |
O_CLOEXEC | 把FD_CLOEXEC常量设置为文件描述符标志 |
O_CREAT | 文件不存在,则创建它 |
O_DIRECTORY | 如果path不是目录,则出错 |
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 | 每次write等待物理I/O操作完成,如果写操作不影响读取刚写入的数据,则不需要等待文件属性更新 |
O_RSYNC | 使每一个以文件描述符进行的read操作等待,直至所用对文件同一部分挂起的写操作都完成 |
第三个参数将在文件权限访问中说明。
open函数返回的文件描述符一定是最小的未用描述符数值。例如,关闭标准输出(1),然后打开一个文件,我们可以确定返回的文件描述符数值为1.
3.close函数
int close(int fd);
在一个文件关闭时,进程会释放加在该文件上的所有记录锁,进程结束时,内核会自动关闭所有他所打开的文件,所以很多程序中都不显示的调用close。
4.lseek函数
off_t lseek(int fd,off_t offset,int whence);
通常情况下,读,写文件是从当前文件偏移量处开始,读或写完毕后,偏移量增加所读写的字节数。默认情况打开一个文件,除非指定O_APPEND选项,否则偏移量被设置为0。
whence | 意义 |
SEEK_SET | 文件的偏移量设置为距文件开始处offset个字节 |
SEEK_CUR | 文件的偏移量设置为当前偏移量加offset个字节,offset可正可负 |
SEEK_END | 文件的偏移量设置为文件长度加offset,offset可正可负 |
lseek的返回值可能为负,比较lseek的返回值时,应当谨慎,不应测试它是否小于0,而应测试是否等于-1.
文件的偏移量可以大于文件当前的长度,下一次写将增加文件长度,并在文件中构成空洞,没有写的字节都被读为0.文件中的空洞不要求在磁盘上占用存储区,新写的数据需要分配磁盘,而原文件尾端与新开始写位置之间不需要分配磁盘。