文件的打开和关闭

简介: 文件的打开和关闭

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&~umaskumask 为文件权限掩码,默认值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 ,文件描述符 012 位系统自动打开,可以被进程直接使用,因此从 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
目录
相关文章
|
6月前
|
程序员 C语言
文件的打开和关闭
文件的打开和关闭
54 1
|
6月前
|
Java 程序员 C语言
打开与关闭文件
打开与关闭文件
65 1
|
6月前
关闭文件
关闭文件。
39 2
|
6月前
|
网络协议 Linux 网络安全
linuxCentOS 6 7打开关闭端口命令
linuxCentOS 6 7打开关闭端口命令
69 0
|
6月前
|
C语言 Python
编程中打开和关闭文件
编程中打开和关闭文件
39 0
|
6月前
文件的打开关闭
文件的打开关闭。
78 0
|
编译器 数据库 C++
C/C++之文件操作————文件的打开与关闭
C/C++之文件操作————文件的打开与关闭
122 0
|
编译器
文件的打开与关闭
文件的打开与关闭
116 0
文件的打开与关闭
|
存储 开发者 Python
文件的打开和关闭 | 学习笔记
快速学习 文件的打开和关闭
109 0
文件的打开和关闭 | 学习笔记
|
缓存 Linux
流的打开和关闭
流的打开和关闭
146 0