Linux 系统 IO之 open close 函数
文章目录
1. open 函数族
1.1 头文件包含
使用 Linux IO open 函数需要包含如下头文件:
#include <sys/types.h>
//因为形参用到了 mode_t 文件类型(文件创建模式),所以需要包含
#include <sys/stat.h>
#include fcntl.h>
Q:
额,记不住怎么办?
A:
使用命令 man 2 open
查看其帮助手册,在帮助手册中有所有需要包含的头文件。
Q:
为什么是 man 2
,此处 2
是什么意思?
A:
使用 man
命令可以查找常用的命令与系统调用的使用文档,man
共有 9 个章节,其中第 2 章是系统调用(内核提供的函数)
,我们此处要查找的 open
函数正是 系统调用函数
因此精确查找时需要指定章节。如果不指定章节,man
命令会返回第一个找个的 open
该 open
可能不是第 2 章的 open
。
1.2 函数原型
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 openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
1.3 函数功能
open
与 openat
函数均用来打开文件,如果文件不存在,则可以设置 O_CREAT
flag 新建文件。
creat
函数仅可以用来创建文件,该函数完全可以由 open
函数替代:
open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
open
与 openat
之间的区别是什么?
- 如果
openat
函数的pathname
参数是绝对路径,则参数dirfd
无效,此时openat
完全等同于open
。 - 如果
openat
与open
函数中pathname
路径名都是相对路径:
open
函数相对于程序所在目录openat
函数则是相对于 文件描述符 dirfd 引用的目录
- 如果
openat
函数pathname
是相对路径,且dirfd
是特殊值AT_FDCWD
那么此时pathname
相对于程序所在目录
1.4 函数返回值
open
、creat
、openat
三个函数,如果执行成功,返回值为成功打开/创建的文件描述符;如果失败,系统会根据错误类型设置errno,并且此时函数返回值为 -1。
1.5 形参解释
const char *pathname
:是一个字符串常量,用于指定要打开/创建文件的路径,此路径可以是绝对路径亦可以是相对路径。int flag
:用于指定文件的读写权限于追加方式等。O_RDONLY
、O_WRONLY
orO_RDWD
三个读写权限必须选择一个,分别表示:只读
、只写
、读写
。- 下列选项为一些常用的配合上述读写权限的标志,选择多个使用 ** | ** 连接
选项 | 说明 |
---|---|
O_APPEND | 追加模式,写至打开文件的尾部 |
O_CREAT | 若打开文件不存在,创建一个新文件 |
O_TRUNC | 截断模式,可写模式打开后该文件被清空重头写 |
O_NOCTTY | 如果文件为终端,那么终端不可以调用open系统调用的那个进程的控制终端 |
O_EXCL | 如果与 O_CREAT同时使用且文件存在,则返回错误消息 |
… | … |
mode_t mode
:指定文件的权限,如0777
,此时需要注意系统的umask
变量。例如我的 Ubuntu ,umask = 0002,此时0777
要与0002
的反码进行与操作才是最终的权限。int dirfd
:此处需要设计打开目录相关的操作
,该参数用于指定,当前openat
函数所要相对的路径。- 包含头文件
#include <dirent.h>
DIR* dir = opendir("目录名")
int dir_fd = dirfd(dir)
- 包含头文件
1.6 案例程序
1.6.1 open 函数打开一个文件,若该文件不存在则新建
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> // fclose
#include <stdlib.h> //exit
#include <stdio.h> //perror
int main()
{
int fd;
// 光标在 open 身上,2 shift + k 即可跳至帮助文档
// 打开文件,若该文件不存在则创建新文件
fd = open("annNote", O_RDWR | O_CREAT, 0777);
if(fd == -1){
perror("create file");
exit(1);
}
// 关闭文件
int ret = close(fd);
if( ret == -1){
perror("close file");
exit(1);
}
return 0;
}
1.6.2 openat 函数根据相对路径打开一个文件,若不存在则新建
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> // fclose
#include <stdlib.h> // exit
#include <stdio.h> // perror
#include <dirent.h> // opendir closedir dirfd
int main()
{
// 指定相对路径
DIR* dir = opendir("/home/annjeff");
int dir_fd = dirfd(dir);
int fd;
// 光标在 open 身上,2 shift + k 即可跳至帮助文档
// 打开文件,若该文件不存在则创建新文件
fd = openat(dir_fd, "annNote.txt", O_RDWR | O_CREAT, 0777);
if(fd == -1){
perror("create file");
exit(1);
}
// 关闭文件
int ret = close(fd);
closedir(dir);
if( ret == -1){
perror("close file");
exit(1);
}
return 0;
}
2. close 函数
2.1 头文件包含
#include <unistd.h>
2.2 函数原型
int close(int fd);
2.3 函数功能
close
函数用于关闭一个已经打开的文件描述符。
2.4 函数返回值
- 成功关闭已打开文件描述符,则返回0
- 关闭失败,则按错误设置全局变量errno,返回 -1
2.4 形参解释
int fd
:形参很简单,即要关闭的已打开的文件描述符。