pyinotify在文件创建时读取的bug?
我想要在某个文件夹里每次新文件创建时都能解析这个文件。为此,我正在尝试使用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 个回答
1
正如@SilentGhost提到的,你可能是在文件内容还没添加之前就读取了这个文件(也就是说,你收到的是文件创建的通知,而不是文件写入的通知)。
更新:使用pynotify的loop.py示例会把一系列的inotify事件显示在屏幕上。要确定你需要关注哪个事件,可以启动loop.py来监控/tmp目录,然后进行你想要跟踪的文件操作。
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']
结果是我预期的。所以请你试试这个脚本(如果需要的话,记得修改开头的Python版本),并告诉我们你使用的Linux内核、pyinotify和Python的具体版本,以及在这种情况下你观察到了什么?如果能提供更详细的信息,我们可能能找出是什么bug或者异常导致你遇到的问题。谢谢!
3
也许你想等文件关闭后再进行操作?