-2

在limits.h中定义的常量“PIPE_BUF”究竟是如何在linux中工作的。当我在系统调用“read(int fd, void *buf, size_t count);”中将它用作“count”时 ,系统是否调用“读取”,一次返回一个字节并等待它到达文件末尾?下面的代码采用两个命令“last”和“sort”并进行两个 popen 调用。像 ~$foo last sort 在下面的代码中,我不明白为什么如果读取只返回一次所有可用字节,那么 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;
}
4

2 回答 2

1

popen立即执行程序,并创建一个连接到该程序的输入/输出的管道。所有程序同时运行。

read调用会一直等待,直到某些数据(至少一个字节)可用,然后返回所有可用并适合缓冲区的数据。如果管道另一端的程序写入了多个字节,您也将能够读取多个字节。

您需要一个循环,因为其他程序稍后可能会写入更多数据。只有当管道的写端关闭时才read返回零。

于 2013-08-02T07:39:23.833 回答
0

根据 linux-source,没有迹象表明read()系统调用一次会读取 1 个字节。这将是非常愚蠢的,所以我永远不会认为 Torvalds 会接受这一点。

回答你的问题:

read()函数用一些数据填充您的缓冲区,要读取比缓冲区可以容纳的更多的数据,您需要继续调用它,直到您读取了所需的所有内容。这就是为什么你会使用循环。拥有与您正在阅读的文件一样大的缓冲区并不是很有效。

于 2013-08-02T01:48:24.420 回答