Python FtpLib模块应用操作详解


Posted in Python onDecember 12, 2019

本文实例讲述了Python FtpLib模块应用操作。分享给大家供大家参考,具体如下:

Python之FtpLib模块应用

工厂中有这样的应用场景: 需要不间断地把设备电脑生成的数据文件上传到远程文件存储服务器NAS中。

在python自带的标准库中找到ftplib模块,可以帮助实现文件的上传。

场景功能的实现需要做到以下几点:

  • 给定本地路径,上传范围是否包含子文件夹及其文件
  • 限定或不限定 哪些文件类型的文件,文件名包含哪些字符串的文件
  • 文件上传后,本地是否要保留
  • 扫完一次本地路径,进行下次循环的间隔周期
  • 生成log日志方便查看报错与已上传的文件,日志文件保留多久之后要删除

思路是这样子,以上内容设计成一个config 文件进行管控。

1.config.xml文件设置

<?xml version="1.0"?>
<Config>
 <ServerIP>10.16.xx.xx</ServerIP>
 <UserID>cc</UserID>
 <Passwd>xxx</Passwd>
 <LogBackupDay>10</LogBackupDay>
 <UploadCheck>TRUE</UploadCheck>
 <Loop_Sec>30</Loop_Sec>
 <LocalDirectory>C:\Users\Administrator\Desktop\TEST\</LocalDirectory>
 <RemoteDirectory>/DATA/AOI/T1TEST200/</RemoteDirectory>
 <FileExtension>csv</FileExtension>
 <FileNameContain>*</FileNameContain>
 <SubDirectoryCheck>TRUE</SubDirectoryCheck>
 <SubDirectoryCreateCheck>FALSE</SubDirectoryCreateCheck>
 <LocalFileBackupCheck>TRUE</LocalFileBackupCheck>
 <FileCreateTime>80</FileCreateTime>
</Config>
  • LogBackupDay 日志保留天数
  • UploadCheck 是否开启上传
  • Loop_Sec 扫描循环周期
  • LocalDirectory 本地路径,结尾必须有路径分隔符
  • RemoteDirectory 远程路径,结尾必须有路径分隔符
  • FileExtension 文件类型,jpg,txt,py,log等等,为*时不限制文件类型
  • FileNameContain 文件名字符串 , 文件名包含哪些字符串的文件,为*时不限制文件名
  • SubDirectoryCheck 子文件夹的文件是否上传
  • SubDirectoryCreateCheck 远程路径是否创建和本地路径一样的文件夹
  • LocalFileBackupCheck 本地文件是否保留
  • FIleCreateTime 扫描本地路径中创建时间为多少个小时内的文件或文件夹

以下是读取config.xml的代码

from xml.dom.minidom import parse
def readConfig():
  '''读取上传配置'''
  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]
  return conflist

2.相关逻辑实现

文件类型及文件名检验

def checkFileExtension(localfile,extension):
  '''
  检查文件名是否符合需要上传的文件类型
  extension为*时,无文件类型限制上传
  '''
  if extension=="*":
    return True
  elif localfile.endswith(extension):
    return True
  else:
    return False
def checkFileNameContains(localfile,filecontain):
  '''
  检查特定文件名的文件
  filecontain 为 * 时,不限制上传文件名
  '''
  if filecontain=="*":
    return True
  elif filecontain in localfile:
    return True
  else:
    return False

文件上传之后,本地是否保留

def deleteLocalFile(deleteCheck,localfile):
  if not deleteCheck:
    os.remove(localfile)
    logger.info("Remove local file:{}".format(localfile))

只上传创建时间为N个小时内的文件或文件夹

def checkFileModifiedTime(localfile,hour):
  '''只上传创建时间为hour小时内的文件'''
  if os.stat(localfile).st_ctime<time.time()-hour*3600:
    return False
  else:
    return True

生成日志,日志文件保留多久

#创建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
if not os.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)
def deleteLog(days):
  '''删除多少天之前的日志文件'''
  for file2 in os.listdir(log_path):
    logfile=os.path.join(log_path,file2)
    if os.stat(logfile).st_ctime<time.time()-days*24*3600:
      os.remove(logfile)

展开子文件夹及相关判断逻辑

def listFile(ftp,local,remote,subdircreatecheck,extension,filenamecontains,filecreatetime,
localBackupCheck):
  '''递归调用出子文件或子文件夹 
  ftp FTP实例
  local 本地文件[夹]
  remote 远程文件[夹]
  subdircreatecheck 远程是否创建对应的子文件夹
  extension 文件类型
  filecontains 文件名必须包含
  filecreatetime 文件修改时间在多少小时内的
  localBackupCheck 本地文件是否保留
  '''
  for file in os.listdir(local):
    local2=os.path.join(local,file) #路径+文件名为 完整路径
    remote2=remote+'/'+file
    try:
      if not checkFileModifiedTime(local2,filecreatetime):
        continue
      if not subdircreatecheck:
        remote2=remote
      if os.path.isdir(local2):
        try:             #验证ftp远程是否已有目录  
          ftp.cwd(remote2)     #打开远程目录,无法打开则报异常,在异常处理里面创建远程目录
        except Exception as e:
          logger.error("Fail to open directory.")
          logger.info("Open directory: {} fail,so create dir.".format(remote2))
          ftp.mkd(remote2)
          logger.info("ItslocalDir:{}".format(local2))
        listFile(ftp,local2,remote2,subdircreatecheck,extension,filenamecontains,
             filecreatetime,localBackupCheck)
      else:
        if checkFileExtension(local2,extension):
          if checkFileNameContains(local2,filenamecontains):
            remote2=remote+'/'+file
            upload(ftp,local2,remote2)
            deleteLocalFile(local2,localBackupCheck)
    except Exception as e:
      logger.error(e.args[0])

上传及异常检验

远程文件已存在并且大小与本地一致时无需上传,使用ftp.size()对比远程文件与本地文件大小即可,出现异常表明远程文件不存在。

def upload(ftp,localFile,remoteFile):
  '''以二进制形式上传文件
  ftp.size()验证远程文件是否存在并且判断文件大小
  '''
  try:
    if ftp.size(remoteFile)==os.path.getsize(localFile):
      return
  except ftplib.error_perm as err:
    logger.warning("{0}.When upload file:{1}".format(err.args[0],remoteFile))
  except Exception as e:
    logger.warning("other error!")
  uf = open(localFile, 'rb')
  bufsize = 1024 # 设置缓冲器大小
  try:
    ftp.storbinary('STOR ' + remoteFile, uf, bufsize)
    logger.info("File has upload success:{}".format(remoteFile))
  except:
    logger.error("File Upload Fail!:{}".format(remoteFile))
  finally:
    uf.close()

周期循环

logger.info("File Send Program Start!")
while uploadCheck:
  logger.info("File Send Program LoopStart!")
  deleteLog(logBackupDay)
  f=ftplib.FTP(host)
  try:
    ###
  except:
    ###
  finally:
    f.quit()
  logger.info("Loop end,wait for next loop!")
  time.sleep(loopTime)

3.打包exe文件

值的注意的是,64位python环境下打包的exe不能在32位的Win7、xp运行。最后使用32位的python环境进行打包。

pyinstaller -i jftp.ico -F Jftp.py -w

code具体详情请查看github-jftp

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python2.7删除文件夹和删除文件代码实例
Dec 18 Python
python 动态获取当前运行的类名和函数名的方法
Apr 15 Python
简单介绍Python中的RSS处理
Apr 13 Python
在Django中创建第一个静态视图
Jul 15 Python
浅谈Python 中整型对象的存储问题
May 16 Python
Python中的sort()方法使用基础教程
Jan 08 Python
python对于requests的封装方法详解
Jan 03 Python
python dict 相同key 合并value的实例
Jan 21 Python
python集合的创建、添加及删除操作示例
Oct 08 Python
python字符串判断密码强弱
Mar 18 Python
Python Tkinter实例——模拟掷骰子
Oct 24 Python
python如何读取和存储dict()与.json格式文件
Jun 25 Python
Python PyInstaller库基本使用方法分析
Dec 12 #Python
Python + Requests + Unittest接口自动化测试实例分析
Dec 12 #Python
python opencv图片编码为h264文件的实例
Dec 12 #Python
Python pygame绘制文字制作滚动文字过程解析
Dec 12 #Python
详解python 中in 的 用法
Dec 12 #Python
python调用c++返回带成员指针的类指针实例
Dec 12 #Python
在Python中实现函数重载的示例代码
Dec 12 #Python
You might like
php中数字0和空值的区别分析
2014/06/05 PHP
PHP启动windows应用程序、执行bat批处理、执行cmd命令的方法(exec、system函数详解)
2014/10/20 PHP
php函数重载的替代方法--伪重载详解
2015/05/08 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
2016/12/02 PHP
Laravel 实现添加多语言提示信息
2019/10/25 PHP
php 中self,this的区别和操作方法实例分析
2019/11/04 PHP
11款基于Javascript的文件管理器
2009/10/25 Javascript
基于jquery的地址栏射击游戏代码
2011/03/10 Javascript
javascript之典型高阶函数应用介绍
2013/01/10 Javascript
jQuery+.net实现浏览更多内容(改编php版本)
2013/03/28 Javascript
jquery实现图片灯箱明暗的遮罩效果
2013/11/15 Javascript
JSON.parse()和JSON.stringify()使用介绍
2014/06/20 Javascript
清除js缓存的多种方法总结
2016/12/09 Javascript
jQuery实现鼠标点击处心形漂浮的炫酷效果示例
2018/04/12 jQuery
vue-cli构建项目下使用微信分享功能
2018/05/28 Javascript
python备份文件以及mysql数据库的脚本代码
2013/06/10 Python
python安装cx_Oracle模块常见问题与解决方法
2017/02/21 Python
Python编程实现数学运算求一元二次方程的实根算法示例
2017/04/02 Python
python 中的list和array的不同之处及转换问题
2018/03/13 Python
pandas 对series和dataframe进行排序的实例
2018/06/09 Python
python 文件查找及内容匹配方法
2018/10/25 Python
python 实现数字字符串左侧补零的方法
2018/12/04 Python
Python进阶之@property动态属性的实现
2019/04/01 Python
python替换字符串中的子串图文步骤
2019/06/19 Python
PyTorch的深度学习入门教程之构建神经网络
2019/06/27 Python
Python xlrd excel文件操作代码实例
2020/03/10 Python
CSS3结构性伪类选择器九种写法
2012/04/18 HTML / CSS
Sunglasses Shop德国站:欧洲排名第一的太阳镜网站
2017/08/01 全球购物
DJI全球:DJI Global
2021/03/15 全球购物
linux面试题参考答案(6)
2016/06/23 面试题
管理心得体会
2013/12/28 职场文书
2015年工商局个人工作总结
2015/07/23 职场文书
如何利用python和DOS获取wifi密码
2021/03/31 Python
浅谈JS的二进制家族
2021/05/09 Javascript
pytorch finetuning 自己的图片进行训练操作
2021/06/05 Python
Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解
2022/03/21 Java/Android