关于零拷贝技术的相关文章,请参考:【Linux编程】大冒险之零拷贝技术探究
在两个文件描述符之间移动数据,同sendfile( )函数一样,也是零拷贝。
函数原型:
#include
ssize_t splice(int fdin, loff_t *offin, int fdout, loff_t *offout, size_t len, unsigned int flags);
参数意义:
fdin参数:待读取数据的文件描述符。
offin参数:指示从输入数据的何处开始读取,为NULL表示从当前位置。如果fdin是一个管道描述符,则offin必须为NULL。
fdout参数:待写入数据的文件描述符。
offout参数:同offin,不过用于输出数据。
len参数:指定移动数据的长度。
flags参数:表示控制数据如何移动,可以为以下值的按位或:
fdin和fdout必须至少有一个是管道文件描述符。
返回值:
返回值>0:表示移动的字节数。
返回0:表示没有数据可以移动,如果从管道中读,表示管道中没有被写入数据。
返回-1;表示失败,并设置errno。
errno值如下:
在两个管道文件描述符之间复制数据,同是零拷贝。但它不消耗数据,数据被操作之后,仍然可以用于后续操作。
函数原型:
#include
ssize_t tee(int fdin, int fdout, size_t len, unsigned int flags);
参数意义:
fdin参数:待读取数据的文件描述符。
fdout参数:待写入数据的文件描述符。
len参数:表示复制的数据的长度。
flags参数:同splice( )函数。
fdin和fdout必须都是管道文件描述符。
返回值:
返回值>0:表示复制的字节数。
返回0:表示没有复制任何数据。
返回-1:表示失败,并设置errno。
/*splice()和tee()实现将文件"./1.txt"同时拷贝到文件"./2.txt"和"./3.txt"中*/
#include
#include
#include
#include
#include
int main(){
int fd1 = open("./1.txt", O_RDONLY);
int fd2 = open("./2.txt", O_RDWR| O_CREAT | O_TRUNC, 0666);
int fd3 = open("./3.txt", O_RDWR| O_CREAT | O_TRUNC, 0666);
/*用于向"./2.txt"输入数据*/
int pipefd2[2];
/*用于向"./3.txt"输入数据*/
int pipefd3[2];
pipe(pipefd2);
pipe(pipefd3);
/*将fd1文件的内容输入管道pipefd2中*/
splice(fd1, NULL, pipefd2[1], NULL, 10086, SPLICE_F_MORE);
/*将管道pipefd2的内容复制到管道pipefd3中,不消耗管道pipefd2上的数据,管道pipefd2上的数据可以用于后续操作*/
tee(pipefd2[0], pipefd3[1], 10086, SPLICE_F_NONBLOCK);
/*将管道pipefd2的内容写入fd2文件中*/
splice(pipefd2[0], NULL, fd2, NULL, 10086, SPLICE_F_MORE);
/*将管道pipefd3的内容写入fd3文件中*/
splice(pipefd3[0], NULL, fd3, NULL, 10086, SPLICE_F_MORE);
close(fd1);
close(fd2);
close(fd3);
close(pipefd2[0]);
close(pipefd2[1]);
close(pipefd3[0]);
close(pipefd3[1]);
return 0;
}
为了简化操作,程序里省略了错误处理,实际编程中需要加入。
相关文件:
【Linux编程】大冒险之零拷贝技术探究