Мониторинг и чтение новых строк в файле?

Программа использует цикл событий AnyEvent. Программа должна читать новые строки, которые иногда (редко) появляются в текстовом файле в локальной файловой системе. Как я понял, AnyEvent :: io использовать нельзя. Что я могу посоветовать для чтения новых строк из файла?

Эм, объясните это лучше, пожалуйста - вы хотите отслеживать события изменения файла и читать, что с этим было сделано? Или что-то другое? И, пожалуйста, покажите (соответствующие части) "программу".

zdim 09.09.2018 19:09

в файловой системе есть текстовый файл (accept.txt), при запуске perl-скрипт считывает из него строки и продолжает работу. Иногда в файл могут быть добавлены новые строки. После добавления этих строк их необходимо прочитать в программе.

Dmitriy 09.09.2018 21:45

@Dmitriy Можешь попробовать AnyEvent::Inotify::Simple

Håkon Hægland 10.09.2018 00:00

Хорошо, Linux::Inotify2 должен будет обнаружить изменение; см., например, эта почта. Я могу или не смогу опубликовать ответ в разумные сроки. Вам действительно стоит опубликовать соответствующие части вашего кода.

zdim 10.09.2018 00:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
555
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Один из способов - «наблюдать» за файлом с помощью инструмента, который отслеживает и сообщает о событиях в объектах файловой системы.

Пример использования 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 Отредактировано дальше, с комментарием о возможном контексте мониторинга

zdim 13.09.2018 08:23

Другие вопросы по теме