我要阅读程序日志文件,为此我想使用select()和read()
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd = -1;
fd_set fds;
struct timeval tv;
int rc;
char buffer[4096];
char * log_path = "/home/mich/a.txt";
if((fd = open(log_path,O_RDONLY) ) == -1 )
{
printf("error\n");
return -1;
}
while(1)
{
FD_ZERO(&fds);
FD_SET(fd,&fds);
tv.tv_sec = 2;
tv.tv_usec = 0;
rc = select(fd+1, &fds, NULL, NULL, &tv);
if (rc < 0) {
printf("failed\n");
continue;
} else if (rc > 0 && FD_ISSET(fd,&fds)) {
printf("read\n");
} else {
printf("timeout\n");
continue;
}
while ((my_getline(buffer,sizeof(buffer),fd)) > 0)
{
printf("%s",buffer);
}
}
close(fd);
}
my_getline是一个使用read()。
的函数输出:
read
aaa
read
read
read
read
read
bbb
read
read
read
read
...
其中aaa和bbb是读取文件中的行。
这个程序有什么问题?
答案 0 :(得分:4)
select()
告诉您read()
不会阻止。
这包括返回0
以指示文件结束的情况,这可能是你得到的结果。
答案 1 :(得分:2)
select
告诉您fd
上有等待的内容。这不必是一行,可以是单个字节,也可以是已到达文件末尾的信息。在外部puts("####");
循环的末尾添加while
,以查看代码如何处理输入文件。
要了解如何继续读取其他进程附加的文件,请查看unix tail
实用程序(特别是其-f
选项)的一个免费实现的源代码。传统的实现是读取整个文件,睡眠一小段时间(tail
中的1秒),并从上次读取后离开的位置重复。更现代,更具反应性,资源消耗更少但便携性更低的方法使用文件更改通知API(Linux下的inotify,* BSD下的kqueue,......)。