从FTP下载文件时出现Python监视程序错误

从FTP下载文件时出现Python监视程序错误,python,io,ftp,subprocess,python-watchdog,Python,Io,Ftp,Subprocess,Python Watchdog,我正在使用Watchdog监视一个目录,以便每隔一段时间通过ftplib下载新的.xml文件。当Watchdog看到该文件时,_created()上的会触发一个函数来处理/解析xml,但似乎文件下载尚未完成,导致后续函数中出现丢失数据错误 在调用函数之前,我添加了一个time.sleep(1),这减轻了错误,但在现实世界中,添加延迟似乎是一种不可靠的方法。我想知道是否有一种类似于承诺函数的方法可以与延迟相比较。或者我完全误诊了这个问题,有一个简单的答案?欢迎任何建议 仅供参考。。。文件大小可以从

我正在使用Watchdog监视一个目录,以便每隔一段时间通过ftplib下载新的.xml文件。当Watchdog看到该文件时,_created()上的会触发一个函数来处理/解析xml,但似乎文件下载尚未完成,导致后续函数中出现丢失数据错误

在调用函数之前,我添加了一个time.sleep(1),这减轻了错误,但在现实世界中,添加延迟似乎是一种不可靠的方法。我想知道是否有一种类似于承诺函数的方法可以与延迟相比较。或者我完全误诊了这个问题,有一个简单的答案?欢迎任何建议

仅供参考。。。文件大小可以从大约100K到4-5mg不等

FTP功能
def下载(f):
ftpt=ftplib.FTP(服务器)
ftpt.login(用户名、密码)
ftpt.cwd(ftp_目录)
打印“已连接到FTP目录”
如果f.startswith('TLC-EMAILUPDATE'):
如果操作系统路径存在(dl_dir+f)==0:
fhandle=open(os.path.join(dl_dir,f),'wb')
打印“获取”+f
ftpt.retrbinary('RETR'+f,fhandle.write)
fhandle.close()
elif os.path.exists(dl_dir+f)==1:
打印“文件”,f,“已存在,跳过下载”
ftp=ftplib.ftp(服务器)
ftp.login(用户名、密码)
ftp.cwd(ftp\u dir)
infiles=ftp.nlst()
池=池(4)
map(下载,在文件中)
看门狗
def on_已创建(自身、事件):
self.processfile(事件)
base=os.path.basename(event.src\u path)
如果base.startswith('TLC-EMAILUPDATE'):
打印“加载报告的文件已标记”
xmldoc=event.src_路径
如果os.path.isfile(xmldoc)==1:
打印“文件下载完成”
发送电子邮件(xmldoc)
发送邮件(带睡眠) 异常被抛出到content变量,解析无法从下载的文件中读取任何数据

def发送电子邮件(xmldoc):
时间。睡眠(2)
content=str(解析xml.create模板(xmldoc))
msg=MIMEText(内容,文本\子类型)
msg['Subject']=电子邮件主题
msg['From']=电子邮件发送人
msg['To']=listToStr(电子邮件接收者)
尝试:
smtpObj=SMTP(GMAIL\u SMTP,GMAIL\u SMTP\u端口)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.ehlo()
smtpObj.login(用户=电子邮件发送者,密码=电子邮件传递)
smtpObj.sendmail(EMAIL\u发件人、EMAIL\u收件人、msg.as\u字符串())
smtpObj.quit()
“打印”电子邮件已发送到%s“%e”电子邮件\u收件人
除了SMTPException作为错误:
打印“错误:无法发送电子邮件:{err}”。格式(err=Error)

简单回答:切换到监控
关闭写入事件。唉,这并不直接支持它。要么:

1) 切换到并使用以下代码——仅限Linux,而不是OSX

2) 在任何事件()上使用带
的看门狗

pyinotify示例源代码 下载文件 输出
谢谢Pyinotify和OSX不玩,我们将在沙箱中一起玩。将要加载到linux机器上,我会告诉您发生了什么。@jp_inc:哦,很抱歉。是的,让我知道你发现了什么!
import os, sys

import pyinotify

class VideoComplete(pyinotify.ProcessEvent):
    def process_IN_CLOSE_WRITE(self, event):
        sys.stdout.write(
            'video complete: {}\n'.format(event.pathname)
        )
        sys.stdout.flush()

def main():
    wm = pyinotify.WatchManager()
    notifier = pyinotify.Notifier(
        wm, default_proc_fun=VideoComplete(),
        )
    mask = pyinotify.ALL_EVENTS
    path = os.path.expanduser('~/Downloads/incoming')
    wm.add_watch(path, mask, rec=True, auto_add=True)
    notifier.loop()

if __name__=='__main__':
    main()
echo beer > ~/Downloads/incoming/beer.txt
video complete: /home/johnm/Downloads/incoming/beer.txt