我有一个popen()
执行tail -f sometextfile
. 只要文件流中有数据,显然我可以通过fgets()
. 现在,如果没有来自尾部的新数据,则fgets()
挂起。我试过了ferror()
,feof()
但无济于事。当文件流中没有新内容时,如何确保fgets()
不尝试读取数据?
其中一个建议是select()
。由于这适用于 Windows 平台,因此选择似乎不起作用,因为匿名管道似乎不适用于它(请参阅这篇文章)。
在 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。
fgets()
是阻塞读取,如果没有数据,它应该等到数据可用。
您需要使用 、 或 来执行异步 I select()
/ poll()
O epoll()
。然后在有可用数据时从文件描述符中执行读取。
这些函数使用句柄的文件描述符FILE*
,通过以下方式检索:int fd = fileno(f);
我通过使用线程解决了我的问题,特别_beginthread
是_beginthreadex
。
您可以尝试使用低级 IO 函数(open()、read() 等)读取 sometextfile,就像 tail 本身一样。当没有更多要读取的内容时,read() 返回零,但下次仍会尝试读取更多内容,这与 FILE* 函数不同。