因为它似乎是你打算让从管道中的所有数据的单一读出,我觉得有以下将为你比分隔符+编码或在其他的答案建议miniheader技术更好:
从管(7)用户手册:
如果所有文件描述符参照 管的写入结束一直 封闭,然后尝试读取(2) 从管将看到结束文件 (读(2)将返回0)。
以下示例是从管道(2)手册页取得的,并且已颠倒过来,以便孩子进行写作,父母进行阅读(只是可以肯定)。我还添加了一个可变大小的缓冲区。孩子会睡5秒钟。延迟将确保孩子的出口()与小孩无关(在孩子退出之前,父母将打印完整的一行)。
#include <sys/wait.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
char *
slurpfd(int fd)
{
const int bytes_at_a_time = 2;
char *read_buffer = NULL;
int buffer_size = 0;
int buffer_offset = 0;
int chars_io;
while (1) {
if (buffer_offset + bytes_at_a_time > buffer_size) {
buffer_size = bytes_at_a_time + buffer_size * 2;
read_buffer = realloc(read_buffer, buffer_size);
if (!read_buffer) {
perror("memory");
exit(EXIT_FAILURE);
}
}
chars_io = read(fd,
read_buffer + buffer_offset,
bytes_at_a_time);
if (chars_io <= 0) break;
buffer_offset += chars_io;
}
if (chars_io < 0) {
perror("read");
exit(EXIT_FAILURE);
}
return read_buffer; /* caller gets to free it */
}
int
main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
assert(argc == 2);
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Child writes argv[1] to pipe */
close(pipefd[0]); /* Close unused read end */
write(pipefd[1], argv[1], strlen(argv[1]) + 1);
close(pipefd[1]); /* Reader will see EOF */
/* sleep before exit to make sure that there
will be a delay after the parent prints it's
output */
sleep(5);
exit(EXIT_SUCCESS);
} else { /* Parent reads from pipe */
close(pipefd[1]); /* Close unused write end */
puts(slurpfd(pipefd[0]));
close(pipefd[0]);
wait(NULL); /* Wait for child */
_exit(EXIT_SUCCESS);
}
}
从您的评论我现在明白了,你可能要读取数据变得可用,更新UI或什么的,以反映系统的状态。要做到这一点,以非阻塞(O_NONBLOCK)模式打开管道。重复读取任何可用的内容,直到-1返回并且errno == EAGAIN并执行解析。重复unil读取返回0,这表明孩子已关闭管道。
要为File *函数使用内存缓冲区,可以在GNU C库中使用fmemopen()。
谢谢大家的回复。 通过管道发送数据的子进程基本上是一个工具的输出,其中列出了有关系统的一些统计信息。每次输出的长度都不相同。我已经将STDOUT复制到子节点的管道写入端。 我的理解是,执行该工具后的子进程会自动将输出放在管道的写入端,因为我已经复制了STDOUT。一旦我完成在父项中的等待,我应该可以使用read()从管道中读取数据。如何在父级获取read()的长度? – Dhruv 2009-07-20 00:42:32
我将对收集的输出进行一些解析。由于工具的输出格式非常好,并且有换行符和空格,所以我可以通过使用指针遍历缓冲区,而不是将中间数据存储在磁盘上的文件中,然后使用string.h函数(如sscanf())来更轻松高效地完成此操作。 我想知道如果在管道上做连续的lseek()将有任何帮助来获取数据的大小。 – Dhruv 2009-07-20 00:55:18
请阅读我的答案更新。它会告诉你如何在数据可用时读取数据。 – Inshallah 2009-07-20 01:39:49