python实现支持目录FTP上传下载文件的方法


Posted in Python onJune 03, 2015

本文实例讲述了python实现支持目录FTP上传下载文件的方法。分享给大家供大家参考。具体如下:

该程序支持ftp上传下载文件和目录、适用于windows和linux平台。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ftplib
import os
import sys
class FTPSync(object):
  conn = ftplib.FTP()
  def __init__(self,host,port=21):    
    self.conn.connect(host,port)    
  def login(self,username,password):
    self.conn.login(username,password)
    self.conn.set_pasv(False)
    print self.conn.welcome
  def test(self,ftp_path):
    print ftp_path
    print self._is_ftp_dir(ftp_path)
    #print self.conn.nlst(ftp_path)
    #self.conn.retrlines( 'LIST ./a/b')
    #ftp_parent_path = os.path.dirname(ftp_path)
    #ftp_dir_name = os.path.basename(ftp_path)
    #print ftp_parent_path
    #print ftp_dir_name
  def _is_ftp_file(self,ftp_path):
    try:
      if ftp_path in self.conn.nlst(os.path.dirname(ftp_path)):
        return True
      else:
        return False
    except ftplib.error_perm,e:
      return False
  def _ftp_list(self, line):
    list = line.split(' ')
    if self.ftp_dir_name==list[-1] and list[0].startswith('d'):
      self._is_dir = True
  def _is_ftp_dir(self,ftp_path):
    ftp_path = ftp_path.rstrip('/')
    ftp_parent_path = os.path.dirname(ftp_path)
    self.ftp_dir_name = os.path.basename(ftp_path)
    self._is_dir = False
    if ftp_path == '.' or ftp_path== './' or ftp_path=='':
      self._is_dir = True
    else:
      #this ues callback function ,that will change _is_dir value
      try:
        self.conn.retrlines('LIST %s' %ftp_parent_path,self._ftp_list)
      except ftplib.error_perm,e:
        return self._is_dir    
    return self._is_dir
  def get_file(self,ftp_path,local_path='.'):
    ftp_path = ftp_path.rstrip('/')
    if self._is_ftp_file(ftp_path):    
      file_name = os.path.basename(ftp_path)
      #如果本地路径是目录,下载文件到该目录
      if os.path.isdir(local_path):
        file_handler = open(os.path.join(local_path,file_name), 'wb' )
        self.conn.retrbinary("RETR %s" %(ftp_path), file_handler.write) 
        file_handler.close()
      #如果本地路径不是目录,但上层目录存在,则按照本地路径的文件名作为下载的文件名称
      elif os.path.isdir(os.path.dirname(local_path)):
        file_handler = open(local_path, 'wb' )
        self.conn.retrbinary("RETR %s" %(ftp_path), file_handler.write) 
        file_handler.close()
      #如果本地路径不是目录,且上层目录不存在,则退出
      else:
        print 'EROOR:The dir:%s is not exist' %os.path.dirname(local_path)
    else:
      print 'EROOR:The ftp file:%s is not exist' %ftp_path
  def put_file(self,local_path,ftp_path='.'):
    ftp_path = ftp_path.rstrip('/')
    if os.path.isfile( local_path ):           
      file_handler = open(local_path, "r")
      local_file_name = os.path.basename(local_path)
      #如果远程路径是个目录,则上传文件到这个目录,文件名不变
      if self._is_ftp_dir(ftp_path):
        self.conn.storbinary('STOR %s'%os.path.join(ftp_path,local_file_name), file_handler)
      #如果远程路径的上层是个目录,则上传文件,文件名按照给定命名
      elif self._is_ftp_dir(os.path.dirname(ftp_path)): 
        print 'STOR %s'%ftp_path        
        self.conn.storbinary('STOR %s'%ftp_path, file_handler)
      #如果远程路径不是目录,且上一层的目录也不存在,则提示给定远程路径错误
      else:        
        print 'EROOR:The ftp path:%s is error' %ftp_path
      file_handler.close()
    else:
      print 'ERROR:The file:%s is not exist' %local_path
  def get_dir(self,ftp_path,local_path='.',begin=True): 
    ftp_path = ftp_path.rstrip('/')
    #当ftp目录存在时下载    
    if self._is_ftp_dir(ftp_path):
      #如果下载到本地当前目录下,并创建目录
      #下载初始化:如果给定的本地路径不存在需要创建,同时将ftp的目录存放在给定的本地目录下。
      #ftp目录下文件存放的路径为local_path=local_path+os.path.basename(ftp_path)
      #例如:将ftp文件夹a下载到本地的a/b目录下,则ftp的a目录下的文件将下载到本地的a/b/a目录下
      if begin:
        if not os.path.isdir(local_path):
          os.makedirs(local_path)
        local_path=os.path.join(local_path,os.path.basename(ftp_path))
      #如果本地目录不存在,则创建目录
      if not os.path.isdir(local_path):
        os.makedirs(local_path)
      #进入ftp目录,开始递归查询
      self.conn.cwd(ftp_path)
      ftp_files = self.conn.nlst()
      for file in ftp_files:
        local_file = os.path.join(local_path, file)
        #如果file ftp路径是目录则递归上传目录(不需要再进行初始化begin的标志修改为False)
        #如果file ftp路径是文件则直接上传文件
        if self._is_ftp_dir(file):
          self.get_dir(file,local_file,False)
        else:
          self.get_file(file,local_file)
      #如果当前ftp目录文件已经遍历完毕返回上一层目录
      self.conn.cwd( ".." )
      return
    else:
      print 'ERROR:The dir:%s is not exist' %ftp_path
      return

  def put_dir(self,local_path,ftp_path='.',begin=True):
    ftp_path = ftp_path.rstrip('/')
    #当本地目录存在时上传
    if os.path.isdir(local_path):      
      #上传初始化:如果给定的ftp路径不存在需要创建,同时将本地的目录存放在给定的ftp目录下。
      #本地目录下文件存放的路径为ftp_path=ftp_path+os.path.basename(local_path)
      #例如:将本地文件夹a上传到ftp的a/b目录下,则本地a目录下的文件将上传的ftp的a/b/a目录下
      if begin:        
        if not self._is_ftp_dir(ftp_path):
          self.conn.mkd(ftp_path)
        ftp_path=os.path.join(ftp_path,os.path.basename(local_path))          
      #如果ftp路径不是目录,则创建目录
      if not self._is_ftp_dir(ftp_path):
        self.conn.mkd(ftp_path)

      #进入本地目录,开始递归查询
      os.chdir(local_path)
      local_files = os.listdir('.')
      for file in local_files:
        #如果file本地路径是目录则递归上传目录(不需要再进行初始化begin的标志修改为False)
        #如果file本地路径是文件则直接上传文件
        if os.path.isdir(file):          
          ftp_path=os.path.join(ftp_path,file)
          self.put_dir(file,ftp_path,False)
        else:
          self.put_file(file,ftp_path)
      #如果当前本地目录文件已经遍历完毕返回上一层目录
      os.chdir( ".." )
    else:
      print 'ERROR:The dir:%s is not exist' %local_path
      return
if __name__ == '__main__':
  ftp = FTPSync('192.168.1.110')
  ftp.login('test','test')
  #上传文件,不重命名
  #ftp.put_file('111.txt','a/b')
  #上传文件,重命名
  #ftp.put_file('111.txt','a/112.txt')
  #下载文件,不重命名
  #ftp.get_file('/a/111.txt',r'D:\\')
  #下载文件,重命名
  #ftp.get_file('/a/111.txt',r'D:\112.txt')
  #下载到已经存在的文件夹
  #ftp.get_dir('a/b/c',r'D:\\a')
  #下载到不存在的文件夹
  #ftp.get_dir('a/b/c',r'D:\\aa')
  #上传到已经存在的文件夹
  ftp.put_dir('b','a')
  #上传到不存在的文件夹
  ftp.put_dir('b','aa/B/')

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

Python 相关文章推荐
python中pandas.DataFrame排除特定行方法示例
Mar 12 Python
Python面向对象程序设计之私有属性及私有方法示例
Apr 08 Python
Pandas DataFrame数据的更改、插入新增的列和行的方法
Jun 25 Python
django框架模板语言使用方法详解
Jul 18 Python
Python3.7安装keras和TensorFlow的教程图解
Jun 18 Python
python如果快速判断数字奇数偶数
Nov 13 Python
如何使用selenium和requests组合实现登录页面
Feb 03 Python
tensorflow实现二维平面模拟三维数据教程
Feb 11 Python
将自己的数据集制作成TFRecord格式教程
Feb 17 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
Jun 18 Python
Python应用实现处理excel数据过程解析
Jun 19 Python
浅析python中特殊文件和特殊函数
Feb 24 Python
python实现的DES加密算法和3DES加密算法实例
Jun 03 #Python
python获取各操作系统硬件信息的方法
Jun 03 #Python
wxPython定时器wx.Timer简单应用实例
Jun 03 #Python
Python基于DES算法加密解密实例
Jun 03 #Python
Python使用minidom读写xml的方法
Jun 03 #Python
Python实现程序的单一实例用法分析
Jun 03 #Python
python简单获取本机计算机名和IP地址的方法
Jun 03 #Python
You might like
改德生G88 - 加装等响度低音提升电路
2021/03/02 无线电
joomla内置的表单验证功能使用方法
2010/06/11 PHP
最常用的8款PHP调试工具
2014/07/06 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
2016/01/22 PHP
jQuery Ajax之load()方法
2009/10/12 Javascript
JavaScript Cookie显示用户上次访问的时间和次数
2009/12/08 Javascript
关于jquery动态增减控件的一些想法和小插件
2010/08/01 Javascript
JavaScript内核之基本概念
2011/10/21 Javascript
JQuery循环滚动图片代码
2011/12/08 Javascript
js实现在文本框光标处添加字符的方法介绍
2012/11/24 Javascript
jquery的flexigrid无法显示数据提示获取到数据
2013/07/19 Javascript
初识SmartJS - AOP三剑客
2014/06/08 Javascript
AngularJS 基础ng-class-even指令用法
2016/08/01 Javascript
NodeJs 文件系统操作模块fs使用方法详解
2018/11/26 NodeJs
js 动态校验开始结束时间的实现代码
2020/05/25 Javascript
解决vue props传Array/Object类型值,子组件报错的情况
2020/11/07 Javascript
[01:06]DOTA2亚洲邀请赛专属珍藏-荧煌之礼
2017/03/24 DOTA
[00:44]华丽开场!DOTA2勇士令状带来全新对阵画面
2019/05/15 DOTA
用python结合jieba和wordcloud实现词云效果
2017/09/05 Python
python对html过滤处理的方法
2018/10/21 Python
使用python对文件中的数值进行累加的实例
2018/11/28 Python
python之线程通过信号pyqtSignal刷新ui的方法
2019/01/11 Python
Python Django的安装配置教程图文详解
2019/07/17 Python
python GUI库图形界面开发之PyQt5布局控件QGridLayout详细使用方法与实例
2020/03/06 Python
Python将字典转换为XML的方法
2020/08/01 Python
纯css3实现的动画按钮的实例教程
2014/11/17 HTML / CSS
CSS3 真的会替代 SCSS 吗
2021/03/09 HTML / CSS
阿迪达斯墨西哥官方网站:adidas墨西哥
2017/11/03 全球购物
如何查找网页漏洞
2016/06/22 面试题
敏捷开发的主要原则都有哪些
2015/04/26 面试题
电子银行营销方案
2014/02/22 职场文书
环境科学专业求职信
2014/08/04 职场文书
中学生打架检讨书
2014/10/13 职场文书
2016年校园重阳节广播稿
2015/12/18 职场文书
如何计划开一家便利店?
2019/07/31 职场文书
浅谈哪个Python库才最适合做数据可视化
2021/06/28 Python