「Linux 系统编程」open 函数基本使用方法
1 open 函数
1.1 open 函数简介
open
函数是 Linux 系统中非常核心的系统调用函数,用于 打开或创建一个文件,并返回一个 文件描述符(file descriptor)。
文件描述符是一个小的、非负的整数,在后续的读(read
)、写(write
)等 I/O 操作中,将用来代表被打开的文件。
文件描述符是一个索引值,指向内核为每个进程所维护的该进程打开文件的记录表。每个进程启动时,通常会自动打开三个标准的文件描述符:
整数 | 缩写 | 全名 | 默认指向 | 用途 |
---|---|---|---|---|
0 | STDIN_FILENO |
Standard Input | 键盘 | 用于读取标准输入 |
1 | STDOUT_FILENO |
Standard Output | 终端屏幕 | 用于输出正常信息 |
2 | STDERR_FILENO |
Standard Error | 终端屏幕 | 用于输出错误信息 |
1.2 open 函数所需头文件
使用 open
函数,需要包含以下头文件:
1 |
|
在某些编译环境和系统版本下,只包含 <fcntl.h>
可能就足够了(<fcntl.h>
可能会间接包含其他需要的定义)。
1.3 open 函数原型及参数
open
函数的函数原型有 2 种形式:
1 |
|
-
pathname
:要打开或创建的文件的路径名。 -
flags
:用于指定文件的打开方式。flags
参数通过按位或(|
)操作符组合一个或多个 标志(定义在fcntl.h
中),是函数行为的核心控制参数。标志 主要分为两类:
-
必选标志(只可三选一)
O_RDONLY
: 以只读方式打开文件。O_WRONLY
: 以只写方式打开文件。O_RDWR
: 以可读可写方式打开文件。
-
可选标志(通过
|
与必选标志组合,此处主要是一些常用的标志)O_CREAT
: 如果文件不存在,则 创建文件。使用此标志时,必须提供第三个参数mode
。
O_EXCL
: 如果与O_CREAT
同时使用,并且文件已存在,则open
会失败。这用于 确保创建的是新文件,防止覆盖已有文件。
O_TRUNC
: 如果 文件已经存在并且以可写方式(O_WRONLY
或O_RDWR
)打开,则将其长度截断为 0,即 清空文件内容。
O_APPEND
: 每次进行写操作时,都会将文件指针移动到文件末尾。这保证了即使在多个进程同时写文件时,数据也不会被覆盖,而是 追加到末尾。
O_NONBLOCK
或O_NDELAY
: 以 非阻塞方式 打开文件。对于某些特殊文件(如设备文件、网络文件),即使没有数据可读或暂时无法写入,open
和后续的 I/O 操作也不会被阻塞。
-
-
mode
:指定新创建文件的 访问权限。使用 O_CREAT 标志时,此参数是必须的。权限通常用八进制数表示,如
0644
(-rw-r--r--
)。最终会受到 umask 值的影响(实际权限 = mode & ~umask)。常见的权限位有:S_IRUSR
: 用户(所有者)读权限
S_IWUSR
: 用户(所有者)写权限
S_IXUSR
: 用户(所有者)执行权限
S_IRGRP
: 组用户读权限
S_IWGRP
: 组用户写权限
S_IROTH
: 其他用户读权限
S_IWOTH
: 其他用户写权限也可以直接使用八进制数,如
0644
表示-rw-r--r--
。
1.4 open 函数返回值
成功: 返回一个新的 文件描述符(一个非负整数)。这个值是当前进程未使用的最小文件描述符。
失败: 返回 -1
,并设置全局变量 errno
来指示错误的具体原因(例如,文件不存在、权限不足等)。
可以通过 perror
函数打印错误信息(perror
函数可以自动将 errno 转换为可读的错误消息)。也可以通过 strerror()
函数返回与 errno 值对应的错误字符串。
2 open 基本使用示例
-
以 只读方式 打开一个已有文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <fcntl.h>
#include <stdio.h>
#include <unistd.h> // close 函数
int main() {
int fd;
// 尝试打开文件
fd = open("existing_file.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
// printf("ERROR: %s\n", strerror(errno)); // 需要 errno.h
return 1;
}
printf("File opened successfully with FD: %d\n", fd);
close(fd); // 操作完成后,必须关闭文件描述符
return 0;
}
-
以 写入方式 创建/打开文件(如果存在则清空)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int fd;
// 如果文件不存在则创建,如果存在则清空
// 权限设置为 rw-r--r--
fd = open("new_file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); // 以追加方式打开文件只需将 O_TRUNC 改为 O_APPEND
if (fd == -1) {
perror("Error creating file");
return 1;
}
printf("File created/truncated successfully with FD: %d\n", fd);
// ... 这里可以进行 write 操作 ...
close(fd);
return 0;
}
3 open 使用注意事项
open
成功返回的文件描述符是一种系统资源,使用完毕后必须用 close()
系统调用关闭,否则会导致 资源泄漏。
不要假设 open
函数会执行成功。一定要检查返回值是否为 -1
,并使用 perror
或检查 errno
来了解失败原因。