pwritev2系统调用及示例

pwritev2 函数

1. 函数介绍

pwritev2 是 pwritev 的增强版本,支持额外的标志参数,提供更多的控制选项。与 preadv2 配对使用。

data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">

pwritev2系统调用及示例-CSDN博客

2. 函数原型

1
2
3
4
#define _GNU_SOURCE
#include <sys/uio.h>
ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);

3. 功能

将多个缓冲区中的数据写入到文件的指定位置,并支持额外的控制标志。

4. 参数

  • int fd: 文件描述符

  • *const struct iovec iov: iovec结构体数组

  • int iovcnt: iov数组元素个数

  • off_t offset: 文件偏移量

  • int flags: 控制标志

5. 返回值

  • 成功: 返回实际写入的总字节数

  • 失败: 返回-1,并设置errno

6. 相似函数,或关联函数

  • pwritev: 基本版本

  • preadv2: 对应的读取函数

  • write: 基本写入函数

7. 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#define _GNU_SOURCE
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

/**
* 演示pwritev2的基本使用
*/
int demo_pwritev2_basic() {
int fd;
struct iovec iov&#91;3];
ssize_t bytes_written;

printf("=== pwritev2 基本使用示例 ===\n");

// 准备要写入的数据
char part1&#91;] = "Part one of the data\n";
char part2&#91;] = "Part two of the data ";
char part3&#91;] = "and part three.\n";

// 创建测试文件
fd = open("test_pwritev2.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd == -1) {
perror("创建测试文件失败");
return -1;
}

// 设置iovec数组
iov&#91;0].iov_base = part1;
iov&#91;0].iov_len = strlen(part1);
iov&#91;1].iov_base = part2;
iov&#91;1].iov_len = strlen(part2);
iov&#91;2].iov_base = part3;
iov&#91;2].iov_len = strlen(part3);

// 使用pwritev2写入数据(flags设为0表示默认行为)
bytes_written = pwritev2(fd, iov, 3, 0, 0);
if (bytes_written == -1) {
if (errno == ENOSYS) {
printf("系统不支持 pwritev2 函数\n");
close(fd);
unlink("test_pwritev2.txt");
return 0;
}
perror("pwritev2 失败");
close(fd);
unlink("test_pwritev2.txt");
return -1;
}

printf("pwritev2 成功写入 %zd 字节\n", bytes_written);

// 读取并验证写入的数据
char buffer&#91;256];
lseek(fd, 0, SEEK_SET);
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
if (bytes_read > 0) {
buffer&#91;bytes_read] = '\0';
printf("\n写入的文件内容:\n%s", buffer);
}

close(fd);
unlink("test_pwritev2.txt");
return 0;
}

/**
* 演示pwritev2的追加写入特性
*/
int demo_pwritev2_append() {
int fd;
struct iovec iov&#91;2];
ssize_t bytes_written;

printf("\n=== pwritev2 追加写入示例 ===\n");

// 创建初始文件
fd = open("append_test.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd == -1) {
perror("创建测试文件失败");
return -1;
}

const char *initial_data = "Initial data in the file\n";
write(fd, initial_data, strlen(initial_data));
close(fd);

// 使用pwritev2进行追加写入
fd = open("append_test.txt", O_WRONLY);
if (fd == -1) {
perror("打开文件失败");
return -1;
}

char new_data1&#91;] = "Appended data ";
char new_data2&#91;] = "using pwritev2\n";

iov&#91;0].iov_base = new_data1;
iov&#91;0].iov_len = strlen(new_data1);
iov&#91;1].iov_base = new_data2;
iov&#91;1].iov_len = strlen(new_data2);

// 注意:RWF_APPEND 标志需要内核支持
bytes_written = pwritev2(fd, iov, 2, 0, RWF_APPEND);
if (bytes_written == -1) {
if (errno == ENOSYS || errno == EINVAL) {
printf("系统不支持 RWF_APPEND 标志,使用普通写入\n");
bytes_written = pwritev2(fd, iov, 2, 0, 0);
} else {
perror("pwritev2 追加写入失败");
close(fd);
unlink("append_test.txt");
return -1;
}
}

if (bytes_written > 0) {
printf("追加写入成功,写入 %zd 字节\n", bytes_written);
}

// 显示最终文件内容
char buffer&#91;256];
lseek(fd, 0, SEEK_SET);
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
if (bytes_read > 0) {
buffer&#91;bytes_read] = '\0';
printf("\n最终文件内容:\n%s", buffer);
}

close(fd);
unlink("append_test.txt");
return 0;
}

int main() {
printf("pwritev2 需要 Linux 4.6+ 内核支持\n");

if (demo_pwritev2_basic() == 0) {
demo_pwritev2_append();
printf("\n=== pwritev2 使用总结 ===\n");
printf("优点:支持额外控制标志,功能更强大\n");
printf("注意:需要较新内核版本支持\n");
}
return 0;
}
data-ad-format="auto" data-full-width-responsive="true">