Trailing a Growing File
Problem
You 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
seek:
for (;;) {
while (<FH>) { .... }
sleep $SOMETIME;
seek(FH, 0, 1);
}or the IO::Handle module’s clearerr method:
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
clearerr
method, if supported: it’s in the IO::Handle and FileHandle
modules.
$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
seek
. The seek code given above tries to move zero
bytes from the current position, which nearly always works. It
doesn’t change the current position, but it should clear the
end-of-file condition on the handle so that the next
<LOGFILE> picks up new data.
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 seek code, which remembers the old file position explicitly and returns there ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access