Python FtpLib模块应用操作详解
本文实例讲述了PythonFtpLib模块应用操作。分享给大家供大家参考,具体如下:
Python之FtpLib模块应用
工厂中有这样的应用场景:需要不间断地把设备电脑生成的数据文件上传到远程文件存储服务器NAS中。
在python自带的标准库中找到ftplib模块,可以帮助实现文件的上传。
场景功能的实现需要做到以下几点:
- 给定本地路径,上传范围是否包含子文件夹及其文件
- 限定或不限定哪些文件类型的文件,文件名包含哪些字符串的文件
- 文件上传后,本地是否要保留
- 扫完一次本地路径,进行下次循环的间隔周期
- 生成log日志方便查看报错与已上传的文件,日志文件保留多久之后要删除
思路是这样子,以上内容设计成一个config文件进行管控。
1.config.xml文件设置
10.16.xx.xx cc xxx 10 TRUE 30 C:\Users\Administrator\Desktop\TEST\ /DATA/AOI/T1TEST200/ csv * TRUE FALSE TRUE 80
- LogBackupDay日志保留天数
- UploadCheck是否开启上传
- Loop_Sec扫描循环周期
- LocalDirectory本地路径,结尾必须有路径分隔符
- RemoteDirectory远程路径,结尾必须有路径分隔符
- FileExtension文件类型,jpg,txt,py,log等等,为*时不限制文件类型
- FileNameContain文件名字符串,文件名包含哪些字符串的文件,为*时不限制文件名
- SubDirectoryCheck子文件夹的文件是否上传
- SubDirectoryCreateCheck远程路径是否创建和本地路径一样的文件夹
- LocalFileBackupCheck本地文件是否保留
- FIleCreateTime扫描本地路径中创建时间为多少个小时内的文件或文件夹
以下是读取config.xml的代码
fromxml.dom.minidomimportparse defreadConfig(): '''读取上传配置''' conf=parse(os.getcwd()+os.sep+'config.xml');#config文件与程序放在同一目录 host=conf.getElementsByTagName("ServerIP")[0].firstChild.data username=conf.getElementsByTagName("UserID")[0].firstChild.data passwd=conf.getElementsByTagName("Passwd")[0].firstChild.data logBackupDay=int(conf.getElementsByTagName("LogBackupDay")[0].firstChild.data) uploadCheck=conf.getElementsByTagName("UploadCheck")[0].firstChild.data uploadLoopTime=int(conf.getElementsByTagName("Loop_Sec")[0].firstChild.data) localDir=conf.getElementsByTagName("LocalDirectory")[0].firstChild.data remoteDir=conf.getElementsByTagName("RemoteDirectory")[0].firstChild.data fileExtension=conf.getElementsByTagName("FileExtension")[0].firstChild.data fileNameContain=conf.getElementsByTagName("TxtFileNameContain")[0].firstChild.data subDirCheck=conf.getElementsByTagName("SubDirectoryCheck")[0].firstChild.data subDirCreateCheck=conf.getElementsByTagName("SubDirectoryCreateCheck")[0].firstChild.data backupCheck=conf.getElementsByTagName("LocalFileBackupCheck")[0].firstChild.data fileCreateTime=int(conf.getElementsByTagName("FileCreateTime")[0].firstChild.data) conflist=[host,username,passwd,logBackupDay,uploadCheck,uploadLoopTime, localDir,remoteDir,fileExtension,fileNameContain, subDirCheck,subDirCreateCheck,backupCheck,fileCreateTime] returnconflist
2.相关逻辑实现
文件类型及文件名检验
defcheckFileExtension(localfile,extension): ''' 检查文件名是否符合需要上传的文件类型 extension为*时,无文件类型限制上传 ''' ifextension=="*": returnTrue eliflocalfile.endswith(extension): returnTrue else: returnFalse defcheckFileNameContains(localfile,filecontain): ''' 检查特定文件名的文件 filecontain为*时,不限制上传文件名 ''' iffilecontain=="*": returnTrue eliffilecontaininlocalfile: returnTrue else: returnFalse
文件上传之后,本地是否保留
defdeleteLocalFile(deleteCheck,localfile): ifnotdeleteCheck: os.remove(localfile) logger.info("Removelocalfile:{}".format(localfile))
只上传创建时间为N个小时内的文件或文件夹
defcheckFileModifiedTime(localfile,hour): '''只上传创建时间为hour小时内的文件''' ifos.stat(localfile).st_ctime生成日志,日志文件保留多久
#创建logger日志 logger=logging.getLogger() logger.setLevel(logging.INFO) #filehandler rq=time.strftime('%Y%m%d',time.localtime(time.time())) log_path=os.getcwd()+os.sep+'Logs'+os.sep ifnotos.path.exists(log_path): os.mkdir(log_path) log_name=log_path+rq+'.log' logfile=log_name fh=logging.FileHandler(logfile,mode='w') fh.setLevel(logging.DEBUG) #filehandler输出格式 formatter=logging.Formatter("%(asctime)s-%(filename)s[line:%(lineno)d]-%(levelname)s:%(message)s") fh.setFormatter(formatter) logger.addHandler(fh)defdeleteLog(days): '''删除多少天之前的日志文件''' forfile2inos.listdir(log_path): logfile=os.path.join(log_path,file2) ifos.stat(logfile).st_ctime展开子文件夹及相关判断逻辑
deflistFile(ftp,local,remote,subdircreatecheck,extension,filenamecontains,filecreatetime, localBackupCheck): '''递归调用出子文件或子文件夹 ftpFTP实例 local本地文件[夹] remote远程文件[夹] subdircreatecheck远程是否创建对应的子文件夹 extension文件类型 filecontains文件名必须包含 filecreatetime文件修改时间在多少小时内的 localBackupCheck本地文件是否保留 ''' forfileinos.listdir(local): local2=os.path.join(local,file)#路径+文件名为完整路径 remote2=remote+'/'+file try: ifnotcheckFileModifiedTime(local2,filecreatetime): continue ifnotsubdircreatecheck: remote2=remote ifos.path.isdir(local2): try:#验证ftp远程是否已有目录 ftp.cwd(remote2)#打开远程目录,无法打开则报异常,在异常处理里面创建远程目录 exceptExceptionase: logger.error("Failtoopendirectory.") logger.info("Opendirectory:{}fail,socreatedir.".format(remote2)) ftp.mkd(remote2) logger.info("ItslocalDir:{}".format(local2)) listFile(ftp,local2,remote2,subdircreatecheck,extension,filenamecontains, filecreatetime,localBackupCheck) else: ifcheckFileExtension(local2,extension): ifcheckFileNameContains(local2,filenamecontains): remote2=remote+'/'+file upload(ftp,local2,remote2) deleteLocalFile(local2,localBackupCheck) exceptExceptionase: logger.error(e.args[0])上传及异常检验
远程文件已存在并且大小与本地一致时无需上传,使用ftp.size()对比远程文件与本地文件大小即可,出现异常表明远程文件不存在。
defupload(ftp,localFile,remoteFile): '''以二进制形式上传文件 ftp.size()验证远程文件是否存在并且判断文件大小 ''' try: ifftp.size(remoteFile)==os.path.getsize(localFile): return exceptftplib.error_permaserr: logger.warning("{0}.Whenuploadfile:{1}".format(err.args[0],remoteFile)) exceptExceptionase: logger.warning("othererror!") uf=open(localFile,'rb') bufsize=1024#设置缓冲器大小 try: ftp.storbinary('STOR'+remoteFile,uf,bufsize) logger.info("Filehasuploadsuccess:{}".format(remoteFile)) except: logger.error("FileUploadFail!:{}".format(remoteFile)) finally: uf.close()周期循环
logger.info("FileSendProgramStart!") whileuploadCheck: logger.info("FileSendProgramLoopStart!") deleteLog(logBackupDay) f=ftplib.FTP(host) try: ### except: ### finally: f.quit() logger.info("Loopend,waitfornextloop!") time.sleep(loopTime)3.打包exe文件
pyinstaller库打包
值的注意的是,64位python环境下打包的exe不能在32位的Win7、xp运行。最后使用32位的python环境进行打包。
pyinstaller-ijftp.ico-FJftp.py-wcode具体详情请查看github-jftp
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python文件与目录操作技巧汇总》、《PythonSocket编程技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》
希望本文所述对大家Python程序设计有所帮助。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。