limits.h 中定义的常量“PIPE_BUF”在linux中是如何工作的。当我在系统调用中使用“count” “read(int fd,void * buf,size_t count);”时,系统会调用 “read”,一次返回一个字节并等待它到达文件末尾? 下面的代码采用两个命令“last”和“sort”并进行两次popen调用。 喜欢〜$ foo最后一种 在下面的代码中,我不明白为什么如果read只返回所有可用字节,那么while循环是必要的。 而且,对popen的写入如何理解所有输入都已被接收,现在是popen执行程序的时候了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
int main (int argc, char* argv[])
{
FILE *fin, *fout;
char buffer[PIPE_BUF];
int n;
if (argc < 3)
{
printf("Need two parameters.\n");
exit(1);
}
fin=popen(argv[1], "r");
fout=popen(argv[2],"w");
fflush(fout);
while ((n=read(fileno(fin), buffer, PIPE_BUF)) > 0)
{
write(fileno(fout), buffer, n);
}
pclose(fin);
pclose(fout);
return 0;
}
答案 0 :(得分:1)
popen
立即执行程序,并创建一个连接到该程序输入/输出的管道。
所有程序同时运行。
read
调用等待一些数据(至少一个字节)可用,然后返回所有可用的数据并放入缓冲区。
如果管道另一端的程序写了多个字节,你也可以读取多个字节。
您需要一个循环,因为其他程序可能会在以后写入更多数据。
只有当管道的写入端关闭时,read
才会返回零。
答案 1 :(得分:0)
根据linux-source,没有迹象表明read()
系统调用一次只能读取1个字节。这将是非常愚蠢的,所以我永远不会认为Torvalds会接受这一点。
回答你的问题:
read()
函数用一些数据填充缓冲区。要读取比缓冲区更多的数据,您需要继续调用它直到您已经阅读了所需的所有内容。这就是你要使用循环的原因。拥有与您正在阅读的文件一样大的缓冲区效率不高。