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
| #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>
int demo_preadv_basic() { int fd; struct iovec iov[3]; char buf1[20], buf2[15], buf3[30]; ssize_t total_bytes; fd = open("test_preadv.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd == -1) { perror("创建测试文件失败"); return -1; } const char *test_data = "This is a long test string for preadv demonstration purposes."; write(fd, test_data, strlen(test_data)); close(fd); fd = open("test_preadv.txt", O_RDONLY); if (fd == -1) { perror("打开文件失败"); return -1; } printf("=== preadv 基本使用示例 ===\n"); printf("测试数据: %s\n", test_data); printf("数据长度: %zu 字节\n\n", strlen(test_data)); iov[0].iov_base = buf1; iov[0].iov_len = sizeof(buf1) - 1; iov[1].iov_base = buf2; iov[1].iov_len = sizeof(buf2) - 1; iov[2].iov_base = buf3; iov[2].iov_len = sizeof(buf3) - 1; total_bytes = preadv(fd, iov, 3, 0); if (total_bytes == -1) { perror("preadv 失败"); close(fd); return -1; } printf("preadv 读取了 %zd 字节到3个缓冲区:\n", total_bytes); buf1[iov[0].iov_len] = '\0'; buf2[iov[1].iov_len] = '\0'; buf3[iov[2].iov_len] = '\0'; printf("缓冲区1 (%zu字节): %s\n", iov[0].iov_len, buf1); printf("缓冲区2 (%zu字节): %s\n", iov[1].iov_len, buf2); printf("缓冲区3 (%zu字节): %s\n", iov[2].iov_len, buf3); close(fd); unlink("test_preadv.txt"); return 0; }
struct Person { int id; char name[20]; float score; };
int demo_preadv_struct() { int fd; struct iovec iov[3]; struct Person person = {1001, "Alice Johnson", 95.5}; int read_id; char read_name[20]; float read_score; printf("\n=== preadv 读取结构体数据示例 ===\n"); fd = open("person_data.bin", O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd == -1) { perror("创建数据文件失败"); return -1; } write(fd, &person, sizeof(person)); close(fd); fd = open("person_data.bin", O_RDONLY); if (fd == -1) { perror("打开数据文件失败"); return -1; } iov[0].iov_base = &read_id; iov[0].iov_len = sizeof(read_id); iov[1].iov_base = read_name; iov[1].iov_len = sizeof(read_name); iov[2].iov_base = &read_score; iov[2].iov_len = sizeof(read_score); ssize_t bytes_read = preadv(fd, iov, 3, 0); if (bytes_read == -1) { perror("preadv 读取结构体失败"); close(fd); return -1; } printf("读取了 %zd 字节的结构体数据:\n", bytes_read); printf("ID: %d\n", read_id); printf("Name: %s\n", read_name); printf("Score: %.1f\n", read_score); close(fd); unlink("person_data.bin"); return 0; }
int main() { if (demo_preadv_basic() == 0) { demo_preadv_struct(); printf("\n=== preadv 使用总结 ===\n"); printf("优点:一次系统调用读取多个缓冲区,减少系统调用开销\n"); printf("适用场景:读取结构化数据,协议解析,网络数据包处理\n"); } return 0; }
|