基于文件描述符的文件操作
POSIX标准支持另一类无缓冲IO,这些操作都是系统调用,值得注意的是,这里的无缓冲是指没有分配用户态文件缓冲区的意思,在操作文件时,进程会在内核地址空间的内核区里回鹘一个数据结构(文件对象)来管理和文件相关的操作。内核区里面还会维护一个索引数组来管理所有的文件对象,该数组的下标成为文件描述符(file descriptor)。
文件描述符fd是一个非负整数,可以传递给用户,用户在得到fd之后可以定位到关联的文件对象,从而可以执行各种IO。
模型如图:
打开、创建、关闭文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcnt1.h>
int open(const char* pathname, int flag);//文件名,打开方式
int open(const char* pathname, int flags, mode_t mode);//文件名 打开方式 权限;当flag中有O_CREAT属性时,采用三参数版本的open
int close(int fd); //fd表示文件描述符,是由open函数的返回值
//注意:close(fd)表示fd对应文件对象的引用计数-1,当引用计数为0时,销毁该文件对象。
-
open可以打开一个已存在的文件或者创建一个文件
-
调用close,会是文件的打开引用计数-1,当文件的打开引用计数为0时,文件才会被真正的关闭。
flags的数据类型时int,但在这里并非当作一个普通证书来使用,用户把这个int堪称32bit的集合,不同的bit描述不同的信息。比如最低的两个bit用来描述读写权限。
#define O_RDONLY 00
#define O_WRONLY 01
#define O_WDWR 02
如果需要同时组合两个无关权限,那么可以采用按位或的操作
选项 | 含义 |
---|---|
O_RDONLY | 以只读的方式打开 |
O_WRONLY | 以只写的方式打开 |
O_RDWR | 以读写方式打开 |
O_CREAT | 若文件不存在,则创建文件 |
O_TRUBC | 如果文件存在,将文件的长度截至0 |
O_APPEND | 以追加的方式打开,每次调用write时,文件指针先自动移到文件尾部,用于多进程同写一个文件的情况 |
当flags选项当中存在O_CREAT选项时,open因该使用三参数版本,其中第三个参数mode说明了要创建文件的权限,一般是一个八进制的整型字面值。
int fd = open("file",O_RDWR | O_CREAT, 0666);//表示给666的权限
int main(int argc, char* argv[]){
ARGS_CHECK(argc,2);
int fd = open(argv[1],O_RDWR | O_CREAT , 0666);
ERROR_CHECK(fd,-1,"open"); //检查报错
printf("fd = %d\n",fd);
close(fd);
return 0;
}
在使用open系统调用时,内核会按照最小可用原则分配一个文件描述符,一般情况下,进程一打开就会启动三个文件对象,占用了0、1、2文件描述符,分别关联了标准输入、标准输出、标准错误文件对象,所以此时在打开的文件占用的file discriptor就是3.