readv和writev特點在於允許單個系統調用讀入到或者寫出自一個或多個緩衝區。這些操作分別稱爲分散讀和集中寫。
因爲來自讀操作的輸入數據被分散到多個應用緩衝區中,而來自多個應用緩衝區的輸出數據則被集中提供給單個寫操作。
ssize_t readv(int filedes, const struct iovec *iov, int iovcnt);
ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);
這兩個函數的第二個參數是指向iovec結構數組的一個指針,iov是一個結構數組,它的每個元素指明存儲器中的一個緩衝區:
struct iovec{
void *iov_base; //starting address of buffer
size_t iov_len; //size of buffer
}
writev以順序iov[0],iov[1]至iov[iovcnt-1]從緩衝區中聚集輸出數據。
readv則將讀入的數據按照上述同樣順序散佈到緩衝區中,readv總是先填滿一個緩衝區,然後再填寫下一個。
有了這兩個函數,當想要集中寫出某張鏈表時,只需讓iov數組的各個元素包含鏈表中各個表項的地址和其長度,然後將iov和它的元素個數作爲參數傳遞給writev(),這些數據便可一次寫出。
函數實現:
體會 分散讀出 和 集中寫入 的含義:
#include <stdio.h>
#include <sys/uio.h>
#include <fcntl.h>
#define IOVENT 3
#define PER_IOVENT 5
int main(void)
{
char buf1[PER_IOVENT],buf2[PER_IOVENT],buf3[PER_IOVENT];
struct iovec iov[IOVENT];//分配3個結構體共同存儲 abcdefghijklnmo
iov[0].iov_base = buf1;
iov[0].iov_len = PER_IOVENT;
iov[1].iov_base = buf2;
iov[1].iov_len = PER_IOVENT;
iov[2].iov_base = buf3;
iov[2].iov_len = PER_IOVENT;
int fd = open("a.txt",O_RDWR);
if(fd < 0){
perror("open");
return -1;
}
int rsize = readv(fd, iov, IOVENT);//a.txt的內容 分散讀出 到三個結構體中
printf("buf1 = %s\n",buf1);
printf("buf2 = %s\n",buf2);
printf("buf3 = %s\n",buf3);
close(fd);
fd = open("b.txt", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if(fd < 0){
perror("open");
return -1;
}
int wsize = writev(fd,iov,IOVENT);//三個結構體中的內容 集中寫入 b.txt中
close(fd);
return 0;
}
#if 0
函數執行:
toney@sw2:~/study/network$ ./a.out
buf1 = abcdefghijklnmo
buf2 = fghijklnmo
buf3 = klnmo
toney@sw2:~/study/network$ cat a.txt
abcdefghijklnmo
toney@sw2:~/study/network$ cat b.txt
abcdefghijklnmotoney@sw2:~/study/network$
toney@sw2:~/study/network$
#endif