Reputation: 32408
I have a programme which is writing results to a file and I would like to read in real-time from that file. It is a normal text file and external programme always write a whole line. I need to run it just on a Linux system.
int last_read = 0;
int res;
FILE *file;
char *buf;
char *end = buf + MAXLINE - 1;
int c;
int fileSize;
char *dst;
while (external_programme_is_running()) {
file = fopen(logfile, "r"); //without opening and closing it's not working
fseek(file, 0, SEEK_END);
fileSize = ftell(file);
if (fileSize > last_read) {
fseek(file, last_read, SEEK_SET);
while (!feof(file)) {
dst = buf;
while ((c = fgetc(file)) != EOF && c != '\n' && dst < end)
*dst++ = c;
*dst = '\0';
res = ((c == EOF && dst == buf) ? EOF : dst - buf);
if (res != -1) {
last_read = ftell(file);
parse_result(buf)
}
}
}
fclose(file);
}
Is this a correct approach? Or would it be better to check the modification time and then open the file? Is is possible that reading would crash in case that the file would be modified at the very same time?
Upvotes: 1
Views: 1165
Reputation: 14711
To avoid the need to close, re-open, and re-seek for every loop iteration, call clearerr
on the stream after reading EOF.
Upvotes: 4
Reputation: 40372
There's no problem in reading a file while another process is writing to it. The standard tail -f
utility is used often for that very purpose.
The only caveat is that the writing process must not exclusively lock the file.
Regarding your read code (ie. using fgetc()
), since you said that the writing process will be writing a line at a time, you might want to look at fgets()
instead.
Upvotes: 0
Reputation: 106
You shouldn't have any problems if you read at the same time the other program writes. The worst that would happen is that you wouldn't get to see what was written until the next time you open the file.
Also, your approach of comparing the last seek position to the end of the file is a fine way to look for additions to the file, since the external program is simply writing additional lines. I would recommend adding a sleep(1) at the end of your loop, though, so you don't use a ton of CPU.
Upvotes: 1