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 相关文章推荐
python遍历文件夹并删除特定格式文件的示例
Mar 05 Python
python递归查询菜单并转换成json实例
Mar 27 Python
分享一个可以生成各种进制格式IP的小工具实例代码
Jul 28 Python
Python下简易的单例模式详解
Apr 08 Python
python实现网站用户名密码自动登录功能
Aug 09 Python
Python实现语音识别和语音合成功能
Sep 20 Python
使用pandas实现连续数据的离散化处理方式(分箱操作)
Nov 22 Python
Python解析json代码实例解析
Nov 25 Python
python实现连连看游戏
Feb 14 Python
Python ATM功能实现代码实例
Mar 19 Python
Django REST framwork的权限验证实例
Apr 02 Python
Python3获取cookie常用三种方案
Oct 05 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中str_replace函数使用小结
2008/10/11 PHP
php curl模拟post请求和提交多维数组的示例代码
2015/11/19 PHP
ThinkPHP表单令牌错误的相关解决方法分析
2016/05/20 PHP
PHP面向对象程序设计重载(overloading)操作详解
2019/06/13 PHP
laravel框架select2多选插件初始化默认选中项操作示例
2020/02/18 PHP
PHP变量的作用范围实例讲解
2020/12/22 PHP
网站页面自动跳转实现方法PHP、JSP(上)
2010/08/01 Javascript
js 调用本地exe的例子(支持IE内核的浏览器)
2012/12/26 Javascript
javascript移动设备Web开发中对touch事件的封装实例
2014/06/05 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
sso跨域写cookie的一段js脚本(推荐)
2016/05/25 Javascript
JS实现京东首页之页面顶部、Logo和搜索框功能
2017/01/12 Javascript
js中的DOM模拟购物车功能
2017/03/22 Javascript
vue.js动态数据绑定学习笔记
2017/05/19 Javascript
React Native基础入门之初步使用Flexbox布局
2018/07/02 Javascript
JavaScript或jQuery 获取option value值方法解析
2020/05/12 jQuery
python制作一个桌面便签软件
2015/08/09 Python
详解python3实现的web端json通信协议
2016/12/29 Python
python基于celery实现异步任务周期任务定时任务
2019/12/30 Python
python给图像加上mask,并提取mask区域实例
2020/01/19 Python
Python实现转换图片背景颜色代码
2020/04/30 Python
PyCharm中如何直接使用Anaconda已安装的库
2020/05/28 Python
基于Python实现视频的人脸融合功能
2020/06/12 Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
2020/08/31 Python
python如何写个俄罗斯方块
2020/11/06 Python
什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?
2016/08/13 面试题
什么时候需要进行强制类型转换
2016/09/03 面试题
土木工程建筑专业毕业生求职信
2013/10/21 职场文书
生日宴会答谢词
2014/01/09 职场文书
女方婚礼新郎答谢词
2014/01/11 职场文书
五好党支部事迹材料
2014/02/06 职场文书
领导班子整改方案
2014/10/25 职场文书
大学生逃课检讨书
2015/05/04 职场文书
社区敬老月活动总结
2015/05/07 职场文书
小学语文新课改心得体会
2016/01/22 职场文书
Python机器学习之KNN近邻算法
2021/05/14 Python