ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
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. SolutionRead 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(); } DiscussionWhen 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 AlsoThe |