python watchdog如何检测一个文件创建完成


有人用过 python watchdog来监视目录么?
因为工作需要,需要写个程序监视一个目录,当有文件创建时,将该文件上传到远程FTP服务器。
使用watchdog可以实现监视的功能,但如果我在受监控的目录里放入的是一个较大的文件,就会报
IOError: [Errno 13] Permission denied: u'F:\xiongji.mp4'的错误。
因为它获取的是文件的创建、修改、删除等事件。
如何获取【当一个文件创建完成】的事件呢?
代码执行环境是:windows 7, python 2.7


 import sys
import time
import os
import ftplib
from ConfigParser import SafeConfigParser
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler


class MyConfig():
    def __init__(self):
        self.loaded = False
        self.scp = None

    @staticmethod
    def instance():
        if not hasattr(MyConfig, "_instance"):
            MyConfig._instance = MyConfig()
        return MyConfig._instance

    def load_config(self, filename):
        self.scp = SafeConfigParser()
        self.scp.read(filename)
        self.loaded = True
        return self

    @property
    def loaded(self):
        return self.loaded

    def get_segment(self, segment_name):
        result = {}
        keys = self.scp.options(segment_name)
        for k in keys:
            result[k] = self.scp.get(segment_name,k)
        return result


class MyFTPClient():
    def __init__(self):
        self.loaded = False
        self.ftp = None

    @staticmethod
    def instance():
        if not hasattr(MyFTPClient, "_instance"):
            MyFTPClient._instance = MyFTPClient()
        return MyFTPClient._instance

    @property
    def loaded(self):
        return self.loaded

    def load_config(self, configfile):
        if not MyConfig().instance().loaded:
            MyConfig().instance().load_config(configfile)

        host = MyConfig().instance().get_segment('FTP Config master')['ftp_host']
        self.ftp = ftplib.FTP(host)
        user = MyConfig().instance().get_segment('FTP Config master')['ftp_user']
        passwd = MyConfig().instance().get_segment('FTP Config master')['ftp_passwd']
        ftp_pwd = MyConfig().instance().get_segment('FTP Config master')['ftp_pwd']
        self.ftp.login(user, passwd)
        self.ftp.cwd(ftp_pwd)

    def upload_file(self, file_abs_path):
        command = 'STOR ' + os.path.basename(file_abs_path)
        os.chdir(os.path.dirname(file_abs_path))
        print "FTP command: [%s]" % command
        try:
            ret = self.ftp.storbinary(command, open(file_abs_path, "rb"))
        except ftplib.error_perm, e:
            print e.message
        #except:
        #    print "unknown error."
        #    pass
        print "upload [%s] O.K." % file_abs_path


class MyFileMonitor(FileSystemEventHandler):
    def on_created(self, event):
        super(MyFileMonitor, self).on_created(event)
        if not event.is_directory:
            print "created name:[%s]" % event.src_path

    def on_modified(self, event):
        super(MyFileMonitor, self).on_created(event)
        if not event.is_directory:
            print "modified name:[%s]" % event.src_path
            abs_path = event.src_path
            MyFTPClient().instance().upload_file(abs_path)


def monitor(path):
    event_handler = MyFileMonitor()
    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

if __name__ == '__main__':
    MyConfig.instance().load_config('config.ini')
    MyFTPClient.instance().load_config('config.ini')
    monitor(MyConfig.instance().get_segment('User PC config')['picture_dir'])

python watchdog

白銀色D指輪 10 years, 10 months ago

猜测:当创建时,较大的文件没有完全拷贝完,这时候你访问就会抛出异常,那你sleep一下,继续尝试打开,直到访问这个文件时不抛出异常了,那就说明这个文件创建完了。

【宅腐】曾铁可 answered 10 years, 10 months ago

Your Answer