open() 函数
open()
函数用于创建或打开文件,在打开或创建文件时可以指定文件打开方式及文件的访问权限。
#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);点击复制复制失败已复制
参数 pathnam
e用以指定打开的文件的路径名,如果文件在当前目录下,那么无须指定目录,直接指定文件名。函数返回一个文件描述符,被用于进行读写操作等其他操作。
标志位flags
用以指定进程打开文件的方式。 flags
标志位如下所示:
flags |
打开文件的方式 |
O_RDONLY |
以只读的方式打开文件 |
O_WRONLY |
以只写的方式打开文件 |
O_RDWR |
以读写的方式打开文件 |
O_APPEND |
以追加的方式打开文件 |
O_ASYNC |
设置异步标志位,表示对设备文件操作采用信号通知的方式 |
O_CREAT |
如果文件不存在,自动创建 |
O_EXCL |
如果文件存在,返回错误码 |
O_NONBLOCK |
以非阻塞的方式打开文件,常用于管道操作 |
O_TRUNC |
如果文件存在,截取文件的长度为 0 ,即清空数据 |
flags
标志位的使用与标准I/O中的 fopen()
函数有些类似,唯一不同的是 open()
函数用于一个特定的宏来指定一种单独的模式,而非 fopen()
函数中直接表示全部含义。因此,关于 flags
参数可通过 "|"
组合构成。通过位或,将宏组合,实现标志位的变化。
由于 open()
函数属于直接系统调用,因此该函数除了可以操作普通文件以外,还可以操作设备。
flags
组合的方式如下所示:
open() |
fopen() |
表示意义 |
O_RDONLY |
r |
只读打开文件 |
O_RDWR |
r+ |
读写打开文件 |
O_WRONLY|O_CREAT|O_TRUNC |
w |
只写打开文件,文件不存在则创建,存在则清空数据 |
O_RDWR|O_CREAT|O_TRUNC |
w+ |
读写打开文件,文件不存在则创建,存在则清空数据 |
O_WRONLY|O_CREAT|O_APPEND |
a |
只写打开文件,文件不存在则创建,存在则追加方式 |
O_RDWR|O_CREAT|O_APPEND |
a+ |
读写打开文件,文件不存在则创建,存在则追加方式 |
参数 mode
是否传递,取决于第二个参数 flags
,如果参数 flags
中,指定了 O_CREAT
标志位,则必须指定参数 mode
。参数 mode
表示文件所属用户对文件的执行权限。参见笔记:文件的存取许可权
设想如果创建一个新文件,必须指定该文件所属用户的操作权限。 mode
参数的使用可以参考笔记文件的存取许可权,既可以使用宏定义,也可使用八进制数。通常设置的 mode
值,会被文件权限掩码屏蔽一些权限位。在 Linux
官方手册中,此参数需要执行 mode&~umask
, umask
为文件权限掩码,默认值为 002
。
close() 函数
close()
函数被用来关闭一个文件描述符。语法定义如下:
#include <unistd.h> int close(int fd);点击复制复制失败已复制
参数 fd
为需要关闭的文件描述符。当一个进程终止时,它所有的打开文件都由内核自动关闭。很多程序都使用这一功能,而不是显式地使用 close()
函数关闭打开的文件。
示例
使用文件I/O函数打开文件
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define errlog(errmsg) \ perror(errmsg); \ printf("--%s--%s--%d--\n", __FILE__, __FUNCTION__, __LINE__); \ return -1; int main(int argc, const char *argv[]) { int fd; if ((fd = open("test.txt", O_WRONLY|O_CREAT|O_TRUNC,0664)) <0) { errlog("open error"); } close(fd); return 0; }点击复制复制失败已复制
获取文件描述符的值
#include <fcntl.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #define errlog(errmsg) \ perror(errmsg); \ printf("--%s--%s--%d--\n", __FILE__, __FUNCTION__, __LINE__); \ return -1; int main(int argc, const char *argv[]) { int fd; if ((fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664)) > 0) { printf("fd = %d\n", fd); } close(fd); return 0; }点击复制复制失败已复制
编译运行:
$ gcc main.c && ./a.out fd = 3点击复制复制失败已复制
从运行结果可以看出,获取的文件描述符的值为 3
,文件描述符 0
、 1
、 2
位系统自动打开,可以被进程直接使用,因此从 3
开始。
进程获取文件描述符的最大数量
文件描述符作为一种有限资源,不可以无限获取,一个进程可以使用的最大的文件描述符的值为 1023
,即一个进程最多可以使用 1024
个文件描述符。
注意
文件描述符的值为多少与文件没有直接关系,而是与当前进程已经打开的文件描述符的个数有关系。
#include <fcntl.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #define errlog(errmsg) \ perror(errmsg); \ printf("--%s--%s--%d--\n", __FILE__, __FUNCTION__, __LINE__); \ return -1; int main(int argc, const char *argv[]) { int fd; while (1) { if ((fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664)) > 0) { printf("fd = %d\n", fd); } else { perror("open error"); return -1; } } close(fd); return 0; }点击复制复制失败已复制
编译运行:
$ gcc main.c && ./a.out …… fd = 1021 fd = 1022 fd = 1023 open error: Too many open files