ошибка pyinotify при чтении файла при создании? - PullRequest
3 голосов
/ 26 апреля 2009

Я хочу анализировать файл каждый раз, когда в определенном каталоге создается новый файл. Для этого я пытаюсь использовать pyinotify , чтобы настроить каталог для наблюдения за IN_CREATE событиями ядра и запустить метод parse().

Вот модуль:

from pyinotify import WatchManager,
    ThreadedNotifier, ProcessEvent, IN_CREATE

class Watcher(ProcessEvent):

    watchdir = '/tmp/watch'

    def __init__(self):
        ProcessEvent.__init__(self)
        wm = WatchManager()
        self.notifier = ThreadedNotifier(wm, self)
        wdd = wm.add_watch(self.watchdir, IN_CREATE)
        self.notifier.start()

    def process_IN_CREATE(self, event):
        pfile = self._parse(event.pathname)
        print(pfile)

    def _parse(self, filename):
        f = open(filename)
        file = [line.strip() for line in f.readlines()]
        f.close()
        return file

if __name__ == '__main__':
    Watcher()

Проблема в том, что список, возвращаемый _parse, равен пусто при запуске новым событием создания файла, например, (файл создается в другом окне, когда watcher.py выполняется):

$ python watcher.py
[]

... но как ни странно, он работает из сеанса интерпретатора при прямом вызове.

>>> import watcher
>>> w = watcher.Watcher()
>>> w._parse('/tmp/watch/sample')
['This is a sample file', 'Another line', 'And another...']

Почему это происходит? Самое большее, что я пришёл для отладки этой вещи, - это то, что что-то заставляет pyinotify неправильно читать файл. Но ... почему?

Ответы [ 4 ]

3 голосов
/ 26 апреля 2009

может быть вы хотите дождаться закрытия файла?

1 голос
/ 26 апреля 2009

Я думаю, что решил проблему, используя вместо этого событие IN_CLOSE_WRITE. Я не уверен, что происходило до того, как это не сработало.

@ Алекс: Спасибо, я попробовал ваш скрипт, но я использую более новые версии: Python 2.6.1, pyinotify 0.8.6 и Linux 2.6.28, поэтому он не работает для меня.

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

1 голос
/ 26 апреля 2009

Вот код, который работает для меня, с ядром 2.6.18, Python 2.4.3 и pyinotify 0.7.1 - вы можете использовать разные версии некоторых из них, но важно убедиться, что мы я говорю о тех же версиях, я думаю ...:

#!/usr/bin/python2.4

import os.path
from pyinotify import pyinotify

class Watcher(pyinotify.ProcessEvent):

    watchdir = '/tmp/watch'

    def __init__(self):
        pyinotify.ProcessEvent.__init__(self)
        wm = pyinotify.WatchManager()
        self.notifier = pyinotify.ThreadedNotifier(wm, self)
        wdd = wm.add_watch(self.watchdir, pyinotify.EventsCodes.IN_CREATE)
        print "Watching", self.watchdir
        self.notifier.start()

    def process_IN_CREATE(self, event):
        print "Seen:", event
        pathname = os.path.join(event.path, event.name)
        pfile = self._parse(pathname)
        print(pfile)

    def _parse(self, filename):
        f = open(filename)
        file = [line.strip() for line in f]
        f.close()
        return file

if __name__ == '__main__':
      Watcher()

когда это выполняется в окне терминала, а в другом окне терминала я делаю

echo "ciao" >/tmp/watch/c3

вывод этой программы:

Watching /tmp/watch
Seen: event_name: IN_CREATE   is_dir: False   mask: 256   name: c3   path: /tmp/watch   wd: 1   
['ciao']

как и ожидалось. Поэтому не могли бы вы попробовать этот сценарий (исправляя версию Python в hashbang, если необходимо, конечно) и сообщить нам точные версии ядра Linux, pyinotify и Python, которые вы используете, и что вы наблюдаете в этих точных обстоятельствах? Вполне возможно, с более подробной информацией, мы можем определить, какая ошибка или аномалия вызывает у вас проблемы. Спасибо!

1 голос
/ 26 апреля 2009

Как уже упоминалось @SilentGhost, вы можете читать файл до того, как в него будет добавлено какое-либо содержимое (т. Е. Вы получаете уведомление о создании файла, а не о записи в файл).

Обновление: пример loop.py с tar-архивом pynotify выведет на экран последовательность событий inotify. Чтобы определить, какое событие нужно запустить, запустите loop.py для monitor / tmp, а затем выполните манипулирование файлами, которые вы хотите отслеживать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...