open,write,read用法
时间: 2025-08-02 19:10:56 浏览: 5
<think>我们正在讨论Linux系统调用open, write, read的用法。需要详细说明每个函数的用法,包括参数、返回值等,并给出示例代码。最后按照要求提出3-5个相关问题。
### open系统调用
用于打开或创建一个文件,返回文件描述符。
函数原型:
```c
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
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_TRUNC`, `O_APPEND`等)
- `mode`:当创建新文件时(使用`O_CREAT`),指定文件权限(如`S_IRUSR | S_IWUSR`表示用户可读写)
**返回值**:
- 成功:返回文件描述符(非负整数)
- 失败:返回-1,并设置errno
**示例**:
```c
int fd = open("test.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
```
### write系统调用
向打开的文件描述符写入数据。
函数原型:
```c
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
```
**参数说明**:
- `fd`:文件描述符(由open返回)
- `buf`:要写入的数据的缓冲区
- `count`:要写入的字节数
**返回值**:
- 成功:返回实际写入的字节数(可能小于count)
- 失败:返回-1,并设置errno
**示例**:
```c
char *str = "Hello, World!";
ssize_t n = write(fd, str, strlen(str));
```
### read系统调用
从打开的文件描述符读取数据。
函数原型:
```c
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
```
**参数说明**:
- `fd`:文件描述符
- `buf`:存放读取数据的缓冲区
- `count`:要读取的最大字节数
**返回值**:
- 成功:返回实际读取的字节数(0表示到达文件末尾)
- 失败:返回-1,并设置errno
**示例**:
```c
char buf[128];
ssize_t n = read(fd, buf, sizeof(buf));
```
### 完整示例:文件复制
```c
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main() {
int src_fd = open("src.txt", O_RDONLY);
if (src_fd < 0) { /* 错误处理 */ }
int dst_fd = open("dst.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (dst_fd < 0) { /* 错误处理 */ }
char buffer[1024];
ssize_t bytes_read;
while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) {
ssize_t bytes_written = write(dst_fd, buffer, bytes_read);
if (bytes_written != bytes_read) { /* 写入错误 */ }
}
close(src_fd);
close(dst_fd);
return 0;
}
```
### 注意事项
1. 每次调用`read`和`write`时,文件位置指针会自动移动。
2. 写入时,如果磁盘空间不足,可能只写入部分数据,需检查返回值。
3. 打开文件后,务必检查返回值,确保文件成功打开。
4. 操作完成后,应使用`close`关闭文件描述符。
§§相关问题§§
1. 在什么情况下`write`系统调用返回的字节数会小于请求写入的字节数?
2. 使用`O_APPEND`标志打开文件对写操作有什么影响?
3. 如何用`read`和`write`实现文件内容的倒序复制?
4. 为什么在读取文件时需要使用循环来处理`read`的返回值?
5. 当多个进程同时写入同一个文件时,如何避免数据覆盖?</think>### Linux 系统调用 `open`, `write`, `read` 用法详解
#### 1. **`open()` - 打开/创建文件**
```c
#include <fcntl.h>
#include <sys/stat.h>
int open(const char *pathname, int flags, mode_t mode);
```
**参数说明**:
- `pathname`:文件路径
- `flags`:打开标志(必选其一 + 可选组合):
- 必选:`O_RDONLY`(只读), `O_WRONLY`(只写), `O_RDWR`(读写)
- 可选:`O_CREAT`(不存在则创建), `O_TRUNC`(清空文件), `O_APPEND`(追加写)
- `mode`:文件权限(八进制数),仅`O_CREAT`时需要(如 `0644`)
**示例**:
```c
int fd = open("data.txt", O_RDWR | O_CREAT | O_APPEND, 0644);
// 创建可读写的文件,不存在则创建,追加写入,权限 rw-r--r--
```
#### 2. **`write()` - 写入数据**
```c
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
```
**参数说明**:
- `fd`:`open`返回的文件描述符
- `buf`:待写入数据的缓冲区指针
- `count`:要写入的字节数
**示例**:
```c
char *data = "Hello Linux";
ssize_t bytes = write(fd, data, strlen(data));
// 返回实际写入的字节数(可能小于请求值)
```
#### 3. **`read()` - 读取数据**
```c
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
```
**参数说明**:
- `fd`:文件描述符
- `buf`:存储读取数据的缓冲区
- `count`:缓冲区最大容量
**示例**:
```c
char buffer[256];
ssize_t bytes = read(fd, buffer, sizeof(buffer));
// 返回实际读取字节数(0表示EOF)
```
#### 完整操作示例
```c
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main() {
// 打开文件(不存在则创建)
int fd = open("demo.txt", O_RDWR | O_CREAT, 0644);
// 写入数据
write(fd, "System call\n", 12);
// 重置文件指针到开头
lseek(fd, 0, SEEK_SET);
// 读取数据
char buf[100];
ssize_t n = read(fd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, n); // 输出到终端
close(fd); // 关闭文件
return 0;
}
```
#### 关键注意事项:
1. **文件描述符**:成功时返回非负整数(0/1/2已被标准输入/输出/错误占用)
2. **错误处理**:所有函数失败时返回-1,需检查`errno`
3. **权限设置**:
- `mode`使用八进制:`0644` = 用户可读写,组和其他只读
- 实际权限受`umask`影响(最终权限 = mode & ~umask)
4. **追加模式**:`O_APPEND`保证原子操作,避免多进程竞争
阅读全文
相关推荐




















