2009-04-26 45 views
3

我想在每次在某個目錄中創建一個新文件時解析一個文件。爲此,我試圖使用pyinotify來設置一個目錄來觀察IN_CREATE內核事件,並激發parse()方法。pyinotify在創建時讀取文件的錯誤?

這裏是模塊:

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不能正確讀取文件。但爲什麼?

+0

比賽條件? – SilentGhost 2009-04-26 14:11:08

+0

除了`IN_CREATE`之外,你應該在`IN_MODIFY`上掛鉤。即`pyinotify.IN_CREATE | pyinotify中。IN_MODIFY` – 2013-04-23 04:09:53

回答

3

可能是你想等到文件關閉?

+0

是的,可能就是這樣。但是,我將事件更改爲IN_CLOSE_WRITE,在文件關閉後,它本質上只會觸發*,並且仍然會得到一個空的結果。我還嘗試在_parse()調用之前插入一個簡單的time.sleep(5),但它似乎沒有幫助,因爲實際上根本沒有等待。 :-S 有沒有辦法在Python中等待文件關閉? – imiric 2009-04-26 14:42:21

1

正如@SilentGhost所提到的,您可能在任何內容被添加到文件之前正在讀取文件(即,您將收到文件創建通知,而不是文件寫入通知)。

更新:pynotify tarball的loop.py示例會將inotify事件序列轉儲到屏幕上。要確定需要觸發哪個事件,請啓動loop.py以監視/ tmp,然後執行要跟蹤的文件操作。

+0

請參閱我的回覆。我已將inotify事件更改爲IN_CLOSE_WRITE,併發生同樣的情況。我如何等待文件完成寫作?謝謝你的幫助。 :) – imiric 2009-04-26 14:52:27

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的確切版本,以及你在這些確切的情況下觀察到什麼?很可能有更詳細的信息,我們可以確定哪個錯誤或異常會給你帶來問題。謝謝!

1

我想我通過使用IN_CLOSE_WRITE事件來解決問題。我不確定之前發生了什麼事情使它無法工作。

@Alex:謝謝,我試過了你的腳本,但我使用的是更新的版本:Python 2.6.1,pyinotify 0.8.6和Linux 2.6.28,所以它不適用於我。

這確實是在寫入文件之前解析文件的問題,所以對SilentGhost和DanM的認可是非常值得的。