1
手冊中提到的splice()
可以在兩個任意文件描述符之間傳輸數據,也可以傳輸到socketfd上。如果文件一次發送,這將起作用。因此文件大小必須低於PIPE_BUF_SZ(= 65536)。如何拼接到socketfd上?
但是,如何處理更大的文件?我想了解與sendfile()系統調用的區別。你將如何重寫sendfile()
系統調用?
第二次拼接以Invalid argument
返回。我想這是因爲socketfd不可搜索。
size_t len = 800000; //e.g.
static int do_copy(int in_fd, int out_fd)
{
loff_t in_off = 0, out_off = 0;
static int buf_size = 65536;
off_t len;
int filedes[2];
int err = -1;
if(pipe(filedes) < 0) {
perror("pipe:");
goto out;
}
while(len > 0) {
if(buf_size > len) buf_size = len;
/* move to pipe buffer. */
err = splice(in_fd, &in_off, filedes[1], NULL, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
if(err < 0) {
perror("splice:");
goto out_close;
}
/* move from pipe buffer to out_fd */
err = splice(filedes[0], NULL, out_fd, &out_off, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
if(err < 0) {
perror("splice2:");
goto out_close;
}
len -= buf_size;
}
err = 0;
out_close:
close(filedes[0]);
close(filedes[1]);
out:
return err;
}
這是來自手冊頁: 'EINVAL目標文件系統不支持拼接;目標文件是 以追加模式打開;這兩個文件描述符都沒有引用 一個管道;或給予不可搜索設備的偏移量。「# – vtha
Thx @vtha。如上所述,socketfd似乎是不可搜索的。但是,sendfile()與完全相同的設置+偏移一起工作!據我瞭解,sendfile()或多或少是一個包裝,使用splice()。 –
有趣。我將不得不在我的工作站上測試它。 – vtha