如何使用 C++ 在 Linux 环境下进行文件操作
一、open() 系统调用(Unix/Linux)
1. 核心知识点回顾
-
函数原型
1
2
3
4
5
6
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode); -
参数
pathname:要打开或创建的文件路径(绝对或相对路径)flags:必选标志,只能选其一(O_RDONLY/O_WRONLY/O_RDWR)和可选标志(O_CREAT、O_EXCL、O_APPEND、O_TRUNC等)。mode:当使用O_CREAT标志时需指定权限。创建文件时的权限(如0644)。
-
返回值:文件描述符(整数)或
-1(失败)。 -
特点:无缓冲的底层操作,适合设备驱动、非阻塞 I/O 等场景。
2. 关键标志位
| 标志 | 功能描述 |
|---|---|
O_CREAT |
文件不存在时创建 |
O_EXCL |
与 O_CREAT 联用,文件存在则报错 |
O_TRUNC |
打开时截断文件 |
O_APPEND |
追加模式 |
O_NONBLOCK |
非阻塞模式 |
3. 错误处理
open() 失败时会设置 errno,常见错误码:
-
ENOENT:路径不存在(无O_CREAT标志时)。 -
EACCES:权限不足(如尝试写入只读文件)。 -
EEXIST:文件已存在(使用O_CREAT | O_EXCL时)。 -
EISDIR:路径是目录而非文件。
4. 相关系统调用
-
close(int fd):关闭文件描述符。 -
read(int fd, void *buf, size_t count):从文件读取数据。 -
write(int fd, const void *buf, size_t count):向文件写入数据。 -
lseek(int fd, off_t offset, int whence):移动文件读写位置。 -
creat(const char *pathname, mode_t mode):等价于open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode)。
1 |
|
二、C++ 标准库中的文件操作
C++ 提供了更高级的文件流类,基于对象和异常处理,避免了直接使用系统调用的复杂性。
1. <fstream> 库(推荐方案)
-
主要类
std::ifstream:输入文件流(只读)。std::ofstream:输出文件流(只写)。std::fstream:输入 / 输出文件流(读写)。
示例:打开文件并读写
1 |
|
2. 文件打开模式(std::ios_base::openmode)
| 模式 | 功能描述 |
|---|---|
std::ios::in |
输入模式(读取) |
std::ios::out |
输出模式(写入,默认截断文件) |
std::ios::app |
追加模式(写入到文件末尾) |
std::ios::ate |
打开后定位到文件末尾 |
std::ios::trunc |
打开时截断文件(若已存在) |
std::ios::binary |
二进制模式(避免文本模式转换) |
三、C++17 及以后的文件系统库(<filesystem>)
C++17 引入了更现代化的文件系统操作 API,提供路径处理、文件状态检查等功能。
1. 文件操作示例
1 |
|
2. 优势
-
跨平台:自动处理不同操作系统的路径分隔符(如
/和\)。 -
异常安全:使用 RAII 管理资源,避免手动关闭文件。
-
功能丰富:支持文件遍历、权限管理、硬链接操作等。