pyinotify bug与创建时读取文件?

时间:2009-04-26 14:07:22

标签: python linux

我想在每次在某个目录中创建新文件时解析文件。为此,我尝试使用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 个答案:

答案 0 :(得分:3)

你可能要等到文件关闭?

答案 1 :(得分:1)

正如@SilentGhost所提到的,您可能在将任何内容添加到文件之前读取该文件(即您收到文件创建通知而不是文件写入)。

更新:使用pynotify tarball的loop.py示例会将inotify事件序列转储到屏幕上。要确定需要触发的事件,请启动loop.py以监视/ tmp,然后执行要跟踪的文件操作。

答案 2 :(得分:1)

这里有一些对我有用的代码,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']

正如所料。那么请你试试这个脚本(当然,如果需要,可以在hashbang中修复Python版本)并告诉我们你正在使用的Linux内核,pyinotify和Python的确切版本,以及你在这些确切的环境中观察到了什么?很可能有更详细的信息,我们可以确定哪个错误或异常正在给你带来问题。谢谢!

答案 3 :(得分:1)

我认为我通过使用IN_CLOSE_WRITE事件来解决问题。我不确定之前发生了什么让它无法正常工作。

@Alex:谢谢,我试过你的脚本,但是我使用的是更新的版本:Python 2.6.1,pyinotify 0.8.6和Linux 2.6.28,所以它对我不起作用。

这绝对是在编写文件之前尝试解析文件的问题,所以感谢SilentGhost和DanM搞清楚。