C语言中“tail -f”功能的自定义实现
编辑:最后我用了 inotify。正如 stefanB 所说,inotify 是最合适的选择。我找到一个使用 inotify 来实现 -f 模式的 tail 克隆,链接在这里:inotail。
原始问题内容:
我正在尝试在一个 C 项目中实现 "tail -f" 的逻辑。为了原型开发,我用 Python 写了如下代码:
# A forever loop, each 5 seconds writes a line into file.txt
from time import *
while 1:
sleep(5)
file = open("file.txt", "a")
file.write("This is a test\n")
file.close()
下面的代码会跟踪 file.txt 的末尾(这个文件是由上面的代码更新的)
# tail -f
from time import *
file = open("file.txt", "r")
file.seek(0, 2)
while 1:
line = file.readline()
if not line:
sleep(1)
else:
print line
file.close()
一切都运行得很好,但 C 的实现却不行(没有检查错误的代码)。这里省略了 stdio.h、string.h 和 unistd.h 的包含(颜色化隐藏了头文件的包含代码)。
#define LINE_LEN 256
int main(int argc, char **argv)
{
FILE *f;
char line[LINE_LEN];
f = fopen("file.txt", "r");
fseek(f, 0, SEEK_END);
while (1)
{
fgets(line, LINE_LEN, f);
if (strlen(line) == 0)
{
sleep(1);
}
else
{
printf("Readed: %s", line);
}
}
fclose(f);
return 0;
}
有什么想法吗?
用 poll() 来实现这个功能是不是个好主意,而不是使用目前的解决方案?
提前谢谢你。
3 个回答
3
一旦一个文件指针(FILE *)遇到错误或者到达文件末尾,它的内部状态就会被设置成这样:在后续的调用中,它会继续返回错误或者文件结束的状态。为了让它重新尝试从文件中读取更多数据,你需要在休眠结束后调用 clearerr(f);
来清除这个文件结束的状态。
3
编辑:
看起来 inotify 是个不错的选择。它从 Linux 内核 2.6.13 版本开始就已经包含在内了。这是 IBM DeveloperWorks 上关于 inotify 的一篇文章。
之前的回答:
可以看看 Linux 的 文件变更监控器(在 Linux 内核 2.4.x 及以上版本中)。这是一个框架,允许你订阅文件的变化,当文件发生变化时,内核会给你发送通知。这种方式比轮询要好。
想了解如何轮询文件变化,可以查看 等待文件变化 和 轮询文件变化 这两个部分的 示例。
我还没有尝试过这个。