因爲它似乎是你打算讓從管道中的所有數據的單一讀出,我覺得有以下將爲你比分隔符+編碼或在其他的答案建議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