2009-04-26 16 views
3

新しいファイルが特定のディレクトリに作成されるたびに、ファイルを解析したいと考えています。このため、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() 

問題はそう(ファイルがwatcher.pyながら、別のウィンドウで作成されたように、新しいファイルの作成イベントによってトリガされたとき_parseによって返されたリストがであるということです

$ 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

+0

'IN_CREATE'に加えて' IN_MODIFY'にフックする必要があります。すなわち 'pyinotify.IN_CREATE | pyinotify。IN_MODIFY' –

答えて

3

ファイルが閉じられるまで待つことができますか?

+0

はい、そうかもしれません。しかし、イベントをIN_CLOSE_WRITEに変更しました。これは、ファイルが閉じられた後にのみ*有効になりますが、まだ空の結果が得られます。私も_parse()コールの前に単純なtime.sleep(5)を挿入しようとしましたが、実際には全く待機していなかったので役立たないようでした。 :-S Pythonでファイルが閉じられるのを待つ方法はありますか? – imiric

1

@ SilentGhostが述べたように、コンテンツがファイルに追加される前にファイルを読み込んでいる可能性があります。つまり、ファイルの書き込みではなくファイルの作成が通知されている可能性があります。

更新:pynotify tarballを使用したloop.pyの例では、一連のinotifyイベントが画面にダンプされます。トリガする必要のあるイベントを特定するには、loop.pyを起動して/ tmpを監視し、追跡するファイル操作を実行します。

+0

私の返信をご覧ください。 inotifyイベントをIN_CLOSE_WRITEに変更しました。同じことが起こります。ファイルの書き込みが完了するのを待つ方法はありますか?ご協力いただきありがとうございます。 :) – imiric

+0

あなたのデバッグはあなたの解析機能が動作することを確認しました。イベントの流れに問題があるはずです。 pynotifyサイトには、pynotify.pyにデバッグに使用できるVERBOSEフラグがあると記載されています。私はその使用法を見ていないが、おそらくこのフラグを有効にすると、イベントフローの詳細がわかります。期待している出来事を見ていますか? – DanM

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の正確なリリースを教えてください。かなり詳細な情報があれば、どのバグか異常が問題になっているのかを特定することができます。ありがとう!

1

代わりにIN_CLOSE_WRITEイベントを使用して問題を解決したと思います。その前に何が起こっていたのか分からないので、それが効かないものになった。

@Alex:ありがとう、あなたのスクリプトを試しましたが、私はPython 2.6.1、pyinotify 0.8.6、およびLinux 2.6.28の新しいバージョンを使用しています。

ファイルが書き込まれる前に解析することは間違いありませんでした。そのため、SilentGhostとDanMに感謝しています。

+0

私はIN_CLOSE_CREATEがinotifyイベントであることに気づいていませんでした...そのためにいくつかのサポート文書がありますか? – sadmicrowave

+0

@sadmicrowave申し訳ありませんが、私はあなたが3歳の誤植を見つけたと思います。私の記憶が正しく私に役立つなら、私は 'IN_CLOSE_WRITE'を使って終わりました。 – imiric

関連する問題