我刚发现有sendfile()。在sendfile()的手册页中,它说:
sendfile()比read(2)和write(2)相结合更有效。
因此,我编写了一个函数来使用sendfile()复制文件。
我的代码真的比read(2)和write(2)的组合更高效吗?
/* leftsize is initialized with total size of source file. */
fd_src = open(src_fname, O_RDONLY);
if (fd_src<0){
printf("open failed(%s)\n", src_fname);
return -1;
}
fd_dest = creat(dest_fname, 0666);
if (fd_dest<0){
printf("create failed(%s)\n", dest_fname);
return -1;
}
while (leftsize > 0) {
n = sendfile(fd_dest, fd_src, NULL, max_size);
if (n<0) {
printf("sendfile failed. ret:%d errno:%d\n", n, errno);
}
leftsize -= n;
}发布于 2018-07-20 02:09:17
手册页的第一段说明了这一切:
sendfile()在一个文件描述符和另一个文件描述符之间复制数据。因为这种复制是在内核内完成的,所以sendfile()比read(2)和write(2)的组合更高效,后者需要在用户空间之间传输数据。
因此,sendfile是相当有效的。
但是,您的循环可能不正确地使用sendfile,因为您总是尝试传输max_size,这可能会在文件的最后一块上返回一个错误(EOVERFLOW) (也就是说,您尝试读取比输入文件中保留的更多的内容)。
如果您正确地处理错误案例,这可能会很好。
这还取决于什么是max_size和leftsize实际上是但你没有具体说明。
我假设max_size是一些合理的块限制(例如,max_size = 1024 * 1024;),leftsize是来自以下输入文件的大小:
struct stat st;
fstat(fd_src,&st);
leftsize = st.st_size;所以,为了安全起见,我会这样做:
while (leftsize > 0) {
// get chunk size
n = max_size;
// clip transfer size to remainder of file
if (n > leftsize)
n = leftsize;
n = sendfile(fd_dest, fd_src, NULL, n);
if (n<0) {
printf("sendfile failed. ret:%d errno:%d\n", n, errno);
}
leftsize -= n;
}发布于 2018-07-20 10:13:45
很好,您正在测试返回值,以查看您的函数调用是否成功。但是,对错误消息使用标准错误流是很好的做法:
if (fd_src<0){
fprintf(stderr, "open failed(%s)\n", src_fname);
return -1;
}目前还不清楚代码是否应该在main()中(下次,请发布一个完整的函数,最好是一个完整的、可编译的程序);如果是这样的话,通常使用较小的正数作为退出状态。负数可能会被截断--在我的系统中,当从shell运行时,返回的-1最终成为255。如果您返回的是+1,则接收时不会受到损害。
https://codereview.stackexchange.com/questions/199876
复制相似问题