我有一个日志文件,我想在C中编写一个程序来读取该日志文件,并在达到EOF时等待新数据。
我不想在我的代码中使用tail -f
。
我尝试了以下代码,但它无法正常工作:
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>
#define PATH "/home/sanket/demo.txt"
int main(void)
{
FILE * fp;
int fd;
char * line = NULL;
size_t len = 0;
ssize_t read1;
int notify_fd;
int wd,length ,i=0;
char buffer[EVENT_BUF_LEN];
fp = fopen(PATH, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
fd = fileno(fp);
while (1)
{
read1 = getline(&line, &len, fp);
if(read1 != -1)
printf("%s",line);
else
{
lseek(fd,0,SEEK_DATA);
}
}
if (line)
free(line);
exit(EXIT_SUCCESS);
}
答案 0 :(得分:4)
当您到达文件的第一个末尾时,将设置EOF的输入流标志。必须先清除它才能恢复操作(clearerr(fp)
)。你通常也应该睡觉。 (在与流关联的文件描述符上使用lseek()
并不会有帮助。)
这是一个基于你的代码的程序 - 我不得不改变PATH的值(这不是一个特别好的名字):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define PATH "demo.txt"
int main(void)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
fp = fopen(PATH, "r");
if (fp == NULL)
{
perror(PATH);
exit(EXIT_FAILURE);
}
while (1)
{
if (getline(&line, &len, fp) != -1)
printf("%s",line);
else
{
printf("EOF\n");
sleep(1);
clearerr(fp);
}
}
if (line)
free(line);
return(EXIT_SUCCESS);
}
如果您有一个为文件生成数据的程序,您可以使用它进行测试。我有一个程序dribbler
可以做到这一点:
$ dribbler -f demo.txt -s 1.5 -r 0.5 &
[1] 20678
$ cat demo.txt
0: message written to file
1: message written to file
2: message written to file
$ tail11
0: message written to file
1: message written to file
2: message written to file
3: message written to file
4: message written to file
5: message written to file
EOF
6: message written to file
EOF
EOF
7: message written to file
EOF
8: message written to file
EOF
EOF
9: message written to file
EOF
10: message written to file
EOF
11: message written to file
EOF
EOF
^C
$
dribbler
的选项是:
Usage: dribbler [-hlntV][-s nap.time][-r std.dev][-f outfile][-i infile][-m message][-o openstr][-F format]
-V Print version information and exit
-f outfile Write to named file (dribbler.out)
-h Print this help message and exit
-i infile Read lines from input file
-l Loop back to start of input file on EOF
-m message Write message on each line of output
-n Number lines read from input file
-o openstr Flags passed to fopen() (a+)
-s nap.time Sleep for given interval between writes (1.000 second)
-r std.dev Randomize the time (Gaussian around nap.time with std.dev)
-t Write to standard output instead of file
-F format Printf format to use instead of %zu
因此,它以1.5秒的平均时间写入文件demo.txt
,具有0.5秒标准差的高斯随机分布。
这就是为什么在连续的输出行之间有时会出现2 EOF
个混乱的原因。