如何从Perl中不断更新的文件中读取?

时间:2009-05-27 14:09:26

标签: perl

问候,我想通读文件,进入睡眠状态,然后检查是否有新记录写入文件。如果是,我想处理记录,如果没有回去睡觉并稍后再次检查(在永久循环中)。

我以为我可以做这样的事情,但是在第一次读取文件之后,它似乎永远不会拿起添加到文件中的新记录。

open (LOG, "<log_file") or die ("could not open log_file");

for (;  ;)   
{  
  print "Record Number == $.\n";   

  while ($text=<LOG>)     
  {                       
    chomp ($text);
    print "$text\n";
  }
  sleep (60);

}

close (LOG);

最初读取文件后,上面的脚本只会继续打印文件中最后一条记录的记录号。 我看到了一些关于TailFile软件包的问题,​​但看起来我没有它,而且此时很难加载。我希望有一个vanilla perl解决方案。

提前致谢。

4 个答案:

答案 0 :(得分:12)

File::Tail是你的朋友。

答案 1 :(得分:8)

那是因为你的while循环将在文件句柄返回EOF时终止。在阅读之前,您需要清除EOF标志。

在while循环和睡眠之后使用seek。

seek(LOG, 0, 1);

字面意思是:从当前位置移动零字节。它不会在文件中前进,但会清除下一次读取的EOF条件。

您也可以使用IO :: Handle模块并调用clearerr();

use IO::Handle;
# ...
LOG->clearerr();

最后,如果您愿意使用tie'd文件句柄,可以尝试在CPAN上使用File :: Tail模块。

答案 2 :(得分:3)

Perl常见问题解答涵盖了这一点。有关完整条目,请参阅perldoc -q tail。如果您愿意安装CPAN模块,则应考虑File::Tail

答案 3 :(得分:0)

@ jmanning2k,你碰巧有一个处理这个的链接吗? perl cookbook有以下内容,看起来非常弱......

for (;;) {
     while () { .... }
     sleep $SOMETIME;
     seek(FH, 0, 1);
 }

或IO :: Handle模块更清晰的方法:

use IO::Seekable;
for (;;) {
     while () { .... }
     sleep $SOMETIME;
     FH->clearerr();
 }