8.5. Trailing a Growing FileProblemYou want to read from a continually growing file, but the read fails when you reach the (current) end of file. Solution
Read until the end of file. Sleep, clear the EOF flag, and read some more. Repeat until interrupted. To clear the EOF flag, either use for (;;) { while (<FH>) { .... } sleep $SOMETIME; seek(FH, 0, 1); }
or the IO::Handle module's use IO::Seekable; for (;;) { while (<FH>) { .... } sleep $SOMETIME; FH->clearerr(); } Discussion
When you read to the end of a file, an internal flag is set that prevents further reading. The most direct way to clear this flag is the $naptime = 1; use IO::Handle; open (LOGFILE, "/tmp/logfile") or die "can't open /tmp/logfile: $!"; for (;;) { while (<LOGFILE>) { print } # or appropriate processing sleep $naptime; LOGFILE->clearerr(); # clear stdio error flag }
If that simple approach doesn't work on your system, you may need to use
If that still doesn't work (e.g., it relies on features of your C library's (so-called) standard I/O implementation), then you may need to use the following for (;;) { for ($curpos = tell(LOGFILE); <LOGFILE>; $curpos = tell(LOGFILE)) { # process $_ here } sleep $naptime; seek(LOGFILE, $curpos, 0); # seek to where we had been }
On some kinds of filesystems, the file could be removed while you are reading it. If so, there's probably little reason to continue checking whether it grows. To make the program exit in that case, exit if (stat(LOGFILE))[3] == 0 If you're using the File::stat module, you could write that more readably as: use File::stat; exit if stat(*LOGFILE)->nlink == 0; See Also
The Copyright © 2001 O'Reilly & Associates. All rights reserved. |
|