使用 Splice 将文件复制到标准输出
Using Splice to Copy File to stdout
是否可以使用 splice
系统调用将文件复制到标准输出?这似乎是微不足道的,但我遇到了困难。我尝试了以下代码但没有成功:
void example(char *filename) {
int buf_size = 2048;
FILE* f = fopen(filename, "r");
if (f == NULL){
perror(filename);
exit(1);
}
int fd = fileno(f);
int filedes[2];
if(pipe(filedes) < 0){
perror("pipe");
exit(1);
}
struct stat st;
if (fstat(fd, &st) < 0){
perror("fstat");
exit(1);
}
off_t to_print = st.st_size;
loff_t i_off = 0;
loff_t o_off = 0;
while(to_print > 0){
if(buf_size > to_print) buf_size = to_print;
ssize_t r = splice(fd,&i_off,filedes[1],NULL,buf_size, SPLICE_F_MORE | SPLICE_F_MOVE);
if (r < 0){
perror("splice");
exit(1);
}
r = splice(filedes[0],NULL,STDOUT_FILENO,&o_off,buf_size, SPLICE_F_MORE | SPLICE_F_MOVE);
if (r < 0){
perror("splice2");
exit(1);
}
to_print -= buf_size;
}
close(fd);
close(filedes[0]);
close(filedes[1]);
}
具体来说,第二个拼接因 无效参数 而失败。我对这个例子有什么误解吗?
当 stdout 引用不可搜索的流时调用 splice()
returns EINVAL。我试过你的程序,当 stdout 引用终端时它失败了。但是,当 stdout 被重定向到一个常规文件时它会成功。
您在此调用中提供了一个输出偏移量:
r = splice(filedes[0],NULL,STDOUT_FILENO,&o_off,buf_size, SPLICE_F_MORE | SPLICE_F_MOVE);
...但终端不可搜索。将 &o_off
更改为 NULL
。
是否可以使用 splice
系统调用将文件复制到标准输出?这似乎是微不足道的,但我遇到了困难。我尝试了以下代码但没有成功:
void example(char *filename) {
int buf_size = 2048;
FILE* f = fopen(filename, "r");
if (f == NULL){
perror(filename);
exit(1);
}
int fd = fileno(f);
int filedes[2];
if(pipe(filedes) < 0){
perror("pipe");
exit(1);
}
struct stat st;
if (fstat(fd, &st) < 0){
perror("fstat");
exit(1);
}
off_t to_print = st.st_size;
loff_t i_off = 0;
loff_t o_off = 0;
while(to_print > 0){
if(buf_size > to_print) buf_size = to_print;
ssize_t r = splice(fd,&i_off,filedes[1],NULL,buf_size, SPLICE_F_MORE | SPLICE_F_MOVE);
if (r < 0){
perror("splice");
exit(1);
}
r = splice(filedes[0],NULL,STDOUT_FILENO,&o_off,buf_size, SPLICE_F_MORE | SPLICE_F_MOVE);
if (r < 0){
perror("splice2");
exit(1);
}
to_print -= buf_size;
}
close(fd);
close(filedes[0]);
close(filedes[1]);
}
具体来说,第二个拼接因 无效参数 而失败。我对这个例子有什么误解吗?
当 stdout 引用不可搜索的流时调用 splice()
returns EINVAL。我试过你的程序,当 stdout 引用终端时它失败了。但是,当 stdout 被重定向到一个常规文件时它会成功。
您在此调用中提供了一个输出偏移量:
r = splice(filedes[0],NULL,STDOUT_FILENO,&o_off,buf_size, SPLICE_F_MORE | SPLICE_F_MOVE);
...但终端不可搜索。将 &o_off
更改为 NULL
。