Linux环境编程之文件I/O(二):文件的打开与关闭
(一)
Linux系统中,要对一个文件进行任何操作,必须首先获得它的文件描述符。而获得文件描述符的方式就是利用open/creat函数打开/创建该文件,open/creat函数返回文件描述符。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
Int close(int filedes);
可以看出open类函数有两个,creat函数有一个,close函数有一个。下面分别介绍下open函数、creat函数和close函数。
(二)
int open(const char *pathname, int flags); 仅能打开文件,不能创建文件。
如果打开成功,其返回值是最小未使用的文件描述符。如果打开失败,其返回值是-1。
参数pathname是要打开文件的名字;参数flags用来说明此函数的多个选项,各个选项之间用‘或运算’构成。
int open(const char *pathname, int flags, mode_t mode);创建新文件,此时flags中含有O_CREAT选项。
如果打开成功,其返回值是最小未使用的文件描述符。如果打开失败,其返回值是-1。
oflag的标志有:
O_RDONLY 打开一个供读取的文件
O_WRONLY 打开一个供写入的文件
O_RDWR
打开一个可供读写的文件 // O_RDONLY、O_WRONLY、O_RDWR只能指定其中一个
O_APPEND
写入的所有数据将被追加到文件的末尾
O_CREAT
打开文件,如果文件不存在则建立文件
O_EXCL
如果已经置O_CREAT且文件存在,则强制open() 失败
O_TRUNC
在open() 时,将文件的内容清空
O_CLOEXEC 在进行exec进程替换时关闭打开的文件描述符。
O_NONBLOCK 非阻塞模式
访问权限mode:
S_IRUSR文件所有者的读权限位
S_IWUSR
文件所有者的写权限位
S_IXUSR
文件所有者的执行权限位
S_IRWXU
S_IRUSR | S_IWUSR | S_IXUSR
S_IRGRP
文件用户组的读权限位
S_IWGRP
文件用户组的写权限位
S_IXGRP
文件用户组的执行权限位
S_IRWXG
S_IRGRP | S_IWGRP | S_IXGRP
S_IROTH
文件其他用户的读权限位
S_IWOTH
文件其他用户的写权限位
S_IXOTH
文件其他用户的执行权限位
S_IRWXO
S_IROTH | S_IWOTH | S_IXOTH
示例代码如下:
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> //open 函数所需头文件 #include <sys/stat.h> // mode访问权限所需头文件 int main(void) { int fd; //open函数打开文件失败,返回-1 if(fd = open("test.txt", O_RDONLY) < 0){ printf("open failed.\n"); printf("fd = %d.\n", fd); }else{ printf("fd = %d.\n", fd); } // 用于创建新文件,返回文件描述符 if(fd = open("test.txt", O_CREAT, S_IRUSR) < 0){ printf("open failed.\n"); printf("fd = %d.\n", fd); }else{ printf("fd = %d.\n", fd); } return 0; }编译及运行测试:
编译程序:gcc demo.c 运行测试:./a.out 结果显示: open failed. fd = 1. fd = 0.编程时一般用按照如下方式使用open函数:
int fd; if(fd = open(pathname, oflag) < 0){ printf("open failed.\n"); exit(0); }应用:由open返回的文件描述符一定是最小的未用描述符数值。这一点被某些应用程序用来在标准输入、标准输出或标准出错输出上打开新的文件。例如,一个应用程序可以先关闭标准输出,然后打开另一个文件,执行操作前就能了解到该文件一定会在文件描述符1上打开。
(三)
int creat(const char *pathname, mode_t mode);用于闯进新的文件。
若成功则返回为只写打开的文件描述符,若出错则返回为-1;因为creat函数存在“以只写方式打开所创建的文件”这一不足之处,所以,如果用creat创建一个临时文件,并要先写该文件,然后又读该文件。则必须先调用creat、close、然后再调用open。因为creat函数操作不便,所以现在已经基本不使用该函数了。
(四)
#include <unistd.h>int close(int fd);
close函数所需参数就是用open或creat的返回值所得的的文件描述符,若成功返回0,若出错返回-1。
关闭一个文件时还会释放进程加在该文件上的所有记录锁。当关闭一个进程终止时,内核自动关闭它所有打开的文件。也正是因为这个原因,很多程序员都不显示的用close关闭打开的文件。
示例程序:
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> int main(void) { int fd; if(fd = open("test.txt", O_RDONLY) < 0){ printf("open failed.\n"); printf("fd = %d.\n", fd); }else{ printf("fd = %d.\n", fd); } //创建test.txt if(fd = open("test.txt", O_CREAT, S_IRUSR) < 0){ printf("open failed.\n"); printf("fd = %d.\n", fd); }else{ printf("fd = %d.\n", fd); } //关闭fd if(close(fd)){ printf("close file failed.\n"); }else{ printf("close file success.\n"); } return 0; }运行测试结果:
open failed. fd = 1. fd = 0. close file success.