文件描述符
Linux 系统中,把一切都看做是文件(一切皆文件),当进程打开现有文件或创建新文件时,内核向进程返回一个文件描述符,文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件,所有执行I/O操作的系统调用都会通过文件描述符。
0,1,2分别为标准输入,标准输出,标准错误文件描述符。
一、打开与创建(open函数和creat函数)
open函数
open函数的返回值就是文件的描述符。后续的读(read)写(write)都围绕这这个描述符来操作。
函数原型:
int open(const char *pathname, int flags);
返回值:一个小的整型数,也就是该文件的文件描述符
int open(const char *pathname, int flags, mode_t mode);
返回值::一个小的整型数,也就是该文件的文件描述符
参数说明:
pathname: 要打开的文件名(含路径,缺省为当前路径)
flags:
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
当我们附带了权限后,打开的文件就只能按照这种权限来操作。以上这三个权限只能制定其中一个。下列参数是可以选的:
O_CREAT:若文件不存在则创建它。使用此选项时,需要同时说明第三个参数mode。用其说明该新文件的存取许可权限。可读4、可写2、可执行1。例如0600:可读可写。
O_EXCL:若|同时使用了O_CREAT,而文件已经存在,则出错。意思就是open()函数的返回值为-1。
O_APPEND:每次写时都加入到文件的尾端。例如:原文件的内容是123,新写入的内容为456,那么新文件的内容为123456。
O_TRUNC:如果文件中是有内容的,而且为只读或只写方式打开成功,则将其长度截短为0。例如:原文件的内容为123456,打开后就没有内容了,后续新写入了123,那么新文件的内容就为123。
mode:文件的权限 可读为4,可写为2,可执行为1;如0600,表示该文件的文件拥着者的权限为可读可写,0700,表示可读可写可执行。
用例:
int fd;
fd=open("./file1",O_RDWR);//在当前路径打以可读可写的方式开了file1文件。
int fd;
fd=open("./file1",O_RDWR|O_CREAT,0600);/*在当前路径打以可读可写的方式开了file1文件,
如果没有该文件则创建一个file1文件,文件拥有者的权限为可读可写*/
creat函数
同样creat函数的返回值也是文件描述符。
函数原型:
int creat(const char *pathname, mode_t mode);
返回值:一个小的整型数,也就是该文件的文件描述符
参数说明:
pathname:文件名,(含路径,缺省为当前路径)
mode:创建模式。
宏表示 | 数字 | 意义 |
S_IRUSR | 4 | 可读 |
S_IWUSR | 2 | 可写 |
S_IXUSR | 1 | 可执行 |
S_IRWXR | 7 | 可读可写可执行 |
用例:
int fd;//creat函数使用时数字表示和宏表示都可以的,如下两种表示方法是等价的。
fd=creat("./file1",S_IRWSR);//在当前路径创建了可读可写的file1文件。
fd=creat("./file2",0600);//在当前路径创建了可读可写的file2文件。
二、对文件的写入(write函数)
函数原型:
ssize_t write(int fd, const void *buf, size_t count);
返回值:写入文件的字符个数
参数说明:
fd:文件描述符
buf:用来存放要写入的内容
count:要写入的字节数
用例:
int fd;
fd=open("./file",O_RDWR|O_CREAT,0600);
char *buf="hello world";
write(fd,buf,strlen(buf));//把buf中的字符串写到文件fd中,写了strlen(buf)个字节数
三、对文件的读取(read函数)
函数原型:
ssize_t read(int fd, void *buf, size_t count);
返回值:从文件中读取的字节数
参数说明:
fd:文件描述符
buf:用来存放从文件中读取的内容
count:要读取的字节数
用例:
int fd;
fd=open("./file",O_RDWR|O_CREAT,0600);
char readbuf[128];
read(fd,readbuf,5);//把fd文件前5个字节读取到readbuf中
四、文件的光标移动问题(lseek函数)
在对文件进行写入和读取时要注意光标的位置,否则会产生写入位置不正确,和读取不到内容的情况,此时需要使用lseek函数来对文件的光标位置进行调整。
函数原型:
off_t lseek(int fd, off_t offset, int whence);
返回值:调用成功会返回当前读写位置相对于文件头部起始位置的偏移量,利用这一特性,可以算出文件的大小
int fileSize;
fileSize=lseek(fd,0,SEEK_END);//将光标置于文件末尾,偏移0个字节,返回的值就是文件的大小。
参数说明:
fd:文件描述符
offse:光标偏移的字节数
whence:用于定义参数 offset 偏移量对应的参考值
宏定义 | |
SEEK_SET | 光标置于文件的起始位置 |
SEEK_CUR | 光标就置于文件的光标的当前位置 |
SEEK_END | 光标置于文件的末尾 |
用例:
lseek(fd,0,SEEK_SET);//光标置于文件开头偏移0个字节。将光标移到开头的位置
lseek(fd,0,SEEK_END);//光标置于文件尾巴偏移0个字节。将光标移到尾巴的位置
五、文件的关闭(close函数)
close()关闭一个文件描述符,这样它就不再引用任何文件,可以被重用。
函数原型:
int close(int fd);
返回值:成功返回0,失败返回-1;
参数说明:
fd:文件描述符
用例:
close(fd);//关闭文件fd