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[3]; ssize_t bytes_written; printf("=== pwritev2 基本使用示例 ===\n"); // 准备要写入的数据 char part1[] = "Part one of the data\n"; char part2[] = "Part two of the data "; char part3[] = "and part three.\n"; // 创建测试文件 fd = open("test_pwritev2.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd == -1) { perror("创建测试文件失败"); return -1; } // 设置iovec数组 iov[0].iov_base = part1; iov[0].iov_len = strlen(part1); iov[1].iov_base = part2; iov[1].iov_len = strlen(part2); iov[2].iov_base = part3; iov[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[256]; lseek(fd, 0, SEEK_SET); ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[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[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[] = "Appended data "; char new_data2[] = "using pwritev2\n"; iov[0].iov_base = new_data1; iov[0].iov_len = strlen(new_data1); iov[1].iov_base = new_data2; iov[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[256]; lseek(fd, 0, SEEK_SET); ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[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; }
|