readv & writev

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章