Как я могу прочитать из постоянно обновляемого файла в Perl? - PullRequest
3 голосов
/ 27 мая 2009

Привет, я хочу прочитать файл, заснуть, а затем проверить, не были ли новые записи записаны в файл. Если да, я хочу обработать записи, если нет, вернитесь в спящий режим и проверьте позже (в цикле навсегда).

Я думал, что смогу сделать что-то подобное, но после первого прочтения файла кажется, что он никогда не обнаруживает новые записи, добавленные в файл.

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, но, похоже, у меня его нет, и сейчас было бы сложно загрузить его. Я надеюсь на ванильное решение Perl.

Заранее спасибо.

Ответы [ 4 ]

12 голосов
/ 27 мая 2009

Файл :: Хвост ваш друг.

8 голосов
/ 27 мая 2009

Это потому, что ваш цикл while завершится, когда дескриптор файла вернет EOF. Вам нужно очистить флаг EOF перед чтением.

Используйте поиск после цикла while и сна.

seek(LOG, 0, 1);

Это буквально говорит: переместить нулевые байты из текущей позиции. Он не будет продвигаться в файле, но очищает условие EOF для следующего чтения.

Вы также можете использовать модуль IO :: Handle и вызвать clearerr ();

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

Наконец, если вы хотите использовать файловый дескриптор tie'd, в CPAN вы можете попробовать модуль File :: Tail.

3 голосов
/ 28 мая 2009

Это описано в Perl FAQ. Смотрите perldoc -q tail для полной записи. Если вы готовы установить модуль CPAN , вам следует рассмотреть File :: Tail .

0 голосов
/ 27 октября 2010

@ jmanning2k, у вас есть ссылка для обработки этого? Поваренная книга perl имеет следующее, что кажется очень слабым ...

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

или метод clearerr модуля IO :: Handle:

use IO::Seekable;
for (;;) {
     while () { .... }
     sleep $SOMETIME;
     FH->clearerr();
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...