等待更新文件然后在Perl中读取文件的好方法是什么?

时间:2010-03-02 22:38:26

标签: perl

我想知道是否有办法等待文件更新,然后在更新后从中读取。所以,如果我有file.txt,我想等到写入新内容,然后读取/处理它/等。目前我正在使用Time::HiRes::sleep(.01)进行投票,但我想知道是否有更好的方法。感谢。

2 个答案:

答案 0 :(得分:9)

是的,有更好的方法。在Windows上,您可以使用FileSystemWatcher界面,在Linux上使用inotify

视窗

use Win32::FileSystem::Watcher;

my $watcher = Win32::FileSystem::Watcher->new( "c:\\" );

# or

my $watcher = Win32::FileSystem::Watcher->new(
    "c:\\",
    notify_filter  => FILE_NOTIFY_ALL,
    watch_sub_tree => 1,
);

$watcher->start();
print "Monitoring started.";

sleep(5);

# Get a list of changes since start().
my @entries = $watcher->get_results();

# Get a list of changes since the last get_results()
@entries = $watcher->get_results();

# ... repeat as needed ...

$watcher->stop(); # or undef $watcher

foreach my $entry (@entries) {
    print $entry->action_name . " " . $entry->file_name . "\n";
}

# Restart monitoring

# $watcher->start();
# ...
# $watcher->stop();

LINUX

use Linux::Inotify2;
my $inotify = new Linux::Inotify2();

foreach (@ARGV)
{
  $inotify->watch($_, IN_ALL_EVENTS);
}

while (1)
{
  # By default this will block until something is read
  my @events = $inotify->read();
  if (scalar(@events)==0)
  {
    print "read error: $!";
    last;
  }

  foreach (@events)
  {
    printf "File: %s; Mask: %d\n", $_->fullname, $_->mask;
  }
}

答案 1 :(得分:2)

File::Tail会轮询该文件,但与您的方法相比有一些优势:

  • 根据自上次投票后写入的行数动态重新计算投票时间
  • 如果文件保持不变,轮询将减慢以避免耗尽CPU
  • File :: Tail将检测文件是否已被截断,移动和/或重新创建,并以静默方式为您重新打开文件
  • 它可以绑定常规文件句柄,您可以像平时一样使用它,而无需任何特殊的API或语法。

来自perldoc的例子:

use File::Tail;
my $ref=tie *FH,"File::Tail",(name=>$name);
while (<FH>) {
    print "$_";
}