14

我有一个popen()执行tail -f sometextfile. 只要文件流中有数据,显然我可以通过fgets(). 现在,如果没有来自尾部的新数据,则fgets()挂起。我试过了ferror()feof()但无济于事。当文件流中没有新内容时,如何确保fgets()不尝试读取数据?

其中一个建议是select()。由于这适用于 Windows 平台,因此选择似乎不起作用,因为匿名管道似乎不适用于它(请参阅这篇文章)。

4

5 回答 5

29

在 Linux(或任何 Unix-y 操作系统)中,您可以将 popen() 使用的底层文件描述符标记为非阻塞。

#include <fcntl.h>

FILE *proc = popen("tail -f /tmp/test.txt", "r");
int fd = fileno(proc);

int flags;
flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);

如果没有可用的输入,fgets 将返回 NULL,并将 errno 设置为 EWOULDBLOCK。

于 2008-09-29T18:19:29.127 回答
15

fgets()是阻塞读取,如果没有数据,它应该等到数据可用。

您需要使用 、 或 来执行异步 I select()/ poll()O epoll()。然后在有可用数据时从文件描述符中执行读取。

这些函数使用句柄的文件描述符FILE*,通过以下方式检索:int fd = fileno(f);

于 2008-09-29T17:57:34.467 回答
1

我通过使用线程解决了我的问题,特别_beginthread_beginthreadex

于 2008-10-01T14:44:14.930 回答
0

我会为 IO 使用 POSIX 函数而不是 C 库的函数,你可以使用selectpoll

于 2008-09-29T17:55:13.287 回答
0

您可以尝试使用低级 IO 函数(open()、read() 等)读取 sometextfile,就像 tail 本身一样。当没有更多要读取的内容时,read() 返回零,但下次仍会尝试读取更多内容,这与 FILE* 函数不同。

于 2008-09-29T17:55:49.650 回答