Каков хороший способ подождать, пока файл обновится, а затем прочитать его в Perl? - PullRequest
5 голосов
/ 03 марта 2010

Мне было интересно, есть ли способ дождаться обновления файла, а затем прочитать его после его обновления. Поэтому, если у меня есть file.txt, я хочу подождать, пока что-то новое не будет записано в него, а затем прочитать его / обработать его / и т.д. В настоящее время я опрашиваю, используя Time::HiRes::sleep(.01), но мне интересно, есть ли лучший способ. Спасибо.

Ответы [ 2 ]

9 голосов
/ 03 марта 2010

Да, есть лучший способ. В Windows вы можете использовать интерфейс FileSystemWatcher , в Linux - inotify .

Windows

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;
  }
}
2 голосов
/ 03 марта 2010

File :: Tail опрашивает файл, но имеет несколько преимуществ по сравнению с вашим подходом:

  • Время опроса пересчитывается динамически на основе количества строк, записанных с момента последнего опроса
  • Если файл остается без изменений, опрос замедлится, чтобы не использовать процессор
  • File :: Tail определит, был ли файл обрезан, перемещен и / или воссоздан, и автоматически откроет файл для вас
  • Он может связывать обычный дескриптор файла, который вы можете использовать как обычно, без какого-либо специального API или синтаксиса.

Пример из perldoc:

use File::Tail;
my $ref=tie *FH,"File::Tail",(name=>$name);
while (<FH>) {
    print "$_";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...