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 ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.