【2018-01-19】【转】Linux的readv和writev

发布时间:2026/7/17 6:25:27
【2018-01-19】【转】Linux的readv和writev [历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2018-01-19 标题【转】Linux的readv和writev分类操作系统 / linuxlinux readv/writev 简单笔记本文转自【 http://blog.csdn.net/ieearth/article/details/46730669 】readv和writev函数是Linux中的两个系统调用类似于read和write函数不同的是readv和writev在一次执行过程中可以原子地作用于多个缓冲区这些缓冲区常常是非连续的。readv和writev的原型如下#includesys/uio.hssize_treadv(intfd,conststructiovec*iov,intiovcnt);ssize_twritev(intfd,conststructiovec*iov,intiovcnt);structiovec{void*iov_base;/* Starting address */size_tiov_len;/* Number of bytes to transfer */};readv和writev的第一个参数fd是个文件描述符第二个参数是指向iovec数据结构的一个指针其中iov_base为缓冲区首地址iov_len为缓冲区长度参数iovcnt指定了iovec的个数。函数调用成功时返回读、写的总字节数失败时返回-1并设置相应的errno。在一次函数调用中writev以顺序iov[0]、iov[1]至iov从各缓冲区中聚集输出数据到fdreadv则将从fd读入的数据按同样的顺序散布到各缓冲区中readv总是先填满一个缓冲区然后再填下一个因此writev称为gather outputreadv称为scatter input。先来看一个writev的例子指定了两个缓冲区str0和str1内容输出到标准输出并打印实际输出的字节数。// writevex.c#includestdio.h#includestdlib.h#includeunistd.h#includestring.h#includesys/uio.hintmain(){char*str0hello ;char*str1world ;structioveciov[2];ssize_tnwritten;iov[0].iov_basestr0;iov[0].iov_lenstrlen(str0);iov[1].iov_basestr1;iov[1].iov_lenstrlen(str1);nwrittenwritev(STDOUT_FILENO,iov,2);printf(%ld bytes written.,nwritten);exit(EXIT_SUCCESS);}$ gcc writevex.c $ ./a.out hello world12bytes written.再来看一个readv的例子从标准输入读数据缓冲区为长度是8 - 1的buf1和buf2并打印读到的字节总数和两个缓冲区各自的内容。// readvex.c#includestdio.h#includestdlib.h#includeunistd.h#includestring.h#includesys/uio.hintmain(){charbuf1[8]{0};charbuf2[8]{0};structioveciov[2];ssize_tnread;iov[0].iov_basebuf1;iov[0].iov_lensizeof(buf1)-1;iov[1].iov_basebuf2;iov[1].iov_lensizeof(buf2)-1;nreadreadv(STDIN_FILENO,iov,2);printf(%ld bytes read.,nread);printf(buf1:%s ,buf1);printf(buf2:%s ,buf2);exit(EXIT_SUCCESS);}$ gcc readvex.c $ ./a.out helloreadv11bytes read. buf1: hellore buf2: adv