上記のマニュアルsplice()
は、2つの任意のフィールド記述子の間でデータを転送することもできます。また、socketfdにもデータを転送することができます。これは、ファイルを一度に送信する場合に有効です。したがって、ファイルサイズはPIPE_BUF_SZ(= 65536)より小さくなければなりません。socketfdにスプライスする方法は?
しかし、大きなファイルを処理するにはどうすればよいですか? sendfile()のシステムコールとの違いを理解したい。 sendfile()
システムコールはどのように書き換えますか?
2番目のスプライスは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;
}
これはmanページのものです。 'EINVALターゲットファイルシステムはスプライシングをサポートしていません。ターゲットファイルは、追加モードで開かれた です。どちらのファイル記述子も パイプを参照していません。非セカンダリデバイスに指定されたオフセット。 – vtha
Thx @vtha。上で述べたように、socketfdは見分けがたいようです。しかし、sendfile()は全く同じ設定+オフセットで動作します!私が理解しているように、sendfile()は、splice()を使用して、多かれ少なかれラッパーです。興味深い。 –
私はワークステーションでテストしなければならないでしょう。 – vtha