Программа использует цикл событий AnyEvent. Программа должна читать новые строки, которые иногда (редко) появляются в текстовом файле в локальной файловой системе. Как я понял, AnyEvent :: io использовать нельзя. Что я могу посоветовать для чтения новых строк из файла?
в файловой системе есть текстовый файл (accept.txt), при запуске perl-скрипт считывает из него строки и продолжает работу. Иногда в файл могут быть добавлены новые строки. После добавления этих строк их необходимо прочитать в программе.
Хорошо, Linux::Inotify2
должен будет обнаружить изменение; см., например, эта почта. Я могу или не смогу опубликовать ответ в разумные сроки. Вам действительно стоит опубликовать соответствующие части вашего кода.
Один из способов - «наблюдать» за файлом с помощью инструмента, который отслеживает и сообщает о событиях в объектах файловой системы.
Пример использования Linux :: Inotify2, основанный на синопсисе в документации модуля
use warnings;
use strict;
use feature 'say';
use AnyEvent;
use Linux::Inotify2;
my $file = shift @ARGV || 'growing.txt';
die "Usage: $0 file-to-watch\n" if not $file;
say '';
open my $fh, '<', $file or die "Can't open $file: $!";
print while <$fh>;
my $inotify = Linux::Inotify2->new or die "Can't create inotify object: $!";
$inotify->watch( $file, IN_MODIFY, sub {
my $e = shift;
if ($e->IN_MODIFY) {
print while <$fh>;
}
});
my $inotify_w = AnyEvent->io (
fh => $inotify->fileno, poll => 'r', cb => sub { $inotify->poll }
);
1 while $inotify->poll;
Монитор можно использовать со многими основными инструментами обработки событий. В этом примере используется AnyEvent.
Сначала создайте файл growing.txt
, предположительно с некоторым содержанием. Затем запустите программу и поместите ее в фоновый режим (watcher.pl &
), когда ее строки будут напечатаны. Затем добавьте в файл
echo "new line\nanother" >> growing.txt
и наблюдатель печатает
new line another
Пожалуйста, см. эта почта для получения дополнительных сведений и некоторых общих комментариев, а также изучите документацию по модулю и man inotify
в вашей системе.
Чтобы сделать это вместе с другими вещами, вы можете поместить его в разветвленный процесс и отправлять изменения родительскому объекту по мере их поступления (через pipe
, socketpair
или файлы). Любые события, происходящие во время обработки, по-прежнему обнаруживаются и доставляются как новые события после возврата элемента управления.
Родитель может решить вопрос о чтении когда, выполняя другую работу в цикле с неблокирующим IO::Select::can_read
или с обработчиком сигнала для пользовательского сигнала (SIGUSR1
), который дочерний элемент отправляет после записи в свой конец конвейера.
Это набросок чего-то непростого. Также есть готовые решения. Некоторые варианты из экосистемы AnyEvent
: AnyEvent :: Вилка и другие, AnyEvent :: Subprocess с его механизмом «делегатов», AnyEvent :: Handle для отслеживания этого канала, когда он может быть прочитан.
Все это также требует цикла событий, и в этом случае вся работа выполняется в обработчиках (обратных вызовах). Тогда основная работа может быть проделана, например, в «наблюдателе бездействия», но это может оказаться немного запутанным, и в этом конкретном случае описанный ручной подход к управлению дочерними элементами может оказаться более ясным.
Наиболее подходящее управление монитором зависит от деталей вашей программы.
Если файл был изменен таким образом, чтобы изменить индексный дескриптор, приведенный выше код не сможет это обнаружить. Это может происходить со многими распространенными инструментами, такими как zip
, rsync
и т. д. Для защиты от этого, наряду с возможным исчезновением файлов, вы можете использовать другие флаги для обнаружения этих событий.
$inotify->watch( $file,
IN_MODIFY |IN_ATTRIB | IN_MOVE_SELF | IN_DELETE_SELF,
sub {
my $e = shift;
my $name = $e->fullname;
if ($e->IN_MODIFY) {
print while <$fh>;
}
if ($e->IN_ATTRIB) { say "$name meatadata changed" }
if ($e->IN_MOVE_SELF) { say "$name was moved" }
if ($e->IN_DELETE_SELF) { say "$name was deleted" }
});
Для изменения inode запускается IN_ATTRIB
.
Затем вам может потребоваться повторно открыть файл (и, возможно, сначала найти его). Здесь будет очень полезен отдельный монитор каталогов. Все это также можно сделать, используя только монитор каталогов.
@Dmitriy Отредактировано дальше, с комментарием о возможном контексте мониторинга
Эм, объясните это лучше, пожалуйста - вы хотите отслеживать события изменения файла и читать, что с этим было сделано? Или что-то другое? И, пожалуйста, покажите (соответствующие части) "программу".