0

0

使用python ftp和sftp的实例介绍

高洛峰

高洛峰

发布时间:2017-03-22 11:00:05

|

3245人浏览过

|

来源于php中文网

原创

这篇文章详解使用python ftp和sftp的实例介绍

西安二手网
西安二手网

功能介绍:1:强大的用户管理面版2:分为无需注册的免费发布和VIP注册发布/管理两个系统功能3:注册简便,发布信息管理信息等都相当简单4:用户积分制度5:加入 4 个非常实用的道具(在后台设置道具参数) 标题变色道具 (改变标题颜色) 信息置顶道具 (能使发布信息置顶,使用个数越多,位置越高) 内容贴图道具 (可以发和信息相关的图片) 通过验证道具 (可不通过管理员审核,直

下载
python ftp 上传、下载文件

#获取昨天日期

TODAY = datetime.date.today() 

YESTERDAY = TODAY - datetime.timedelta(days=1)CURRENTDAY=YESTERDAY.strftime('%Y%m%d')

---------------------------------------------------------------------------------------

#!/usr/bin/env
python
# -*- coding: cp936 -*-
#导入ftplib扩展库 
import ftplib 
  
#创建ftp对象实例 

ftp = ftplib.FTP() 
  
#指定IP地址和端口,连接到FTP服务,上面显示的是FTP服务器的Welcome信息 

FTPIP= "218.108.***.***"
FTPPORT= 21
USERNAME= "ybmftp"
USERPWD= "ybm***"

ftp.connect(FTPIP,FTPPORT) 
  
#通过账号和密码登录FTP服务器 

ftp.login(USERNAME,USERPWD) 
  
#如果参数 pasv 为真,打开被动模式传输 (PASV MODE) ,

#否则,如果参数 pasv 为假则关闭被动传输模式。

#在被动模式打开的情况下,数据的传送由客户机启动,而不是由服务器开始。

#这里要根据不同的服务器配置

ftp.set_pasv(0)

#在FTP连接中切换当前目录 

CURRTPATH= "/home1/ftproot/ybmftp/testupg/payment"

ftp.cwd(CURRTPATH) 
  
#为准备下载到本地的文件,创建文件对象 
  
DownLocalFilename="YBM_20110629_9001_CHK"

f = open(DownLocalFilename,'wb') 
  
#从FTP服务器下载文件到前一步创建的文件对象,其中写对象为f.write,1024是缓冲区大小 
  
DownRoteFilename="YBM_20110629_9001_CHK"

ftp.retrbinary('RETR ' + DownRoteFilename , f.write ,1024) 
  
#关闭下载到本地的文件 
  
#提醒:虽然Python可以自动关闭文件,但实践证明,如果想下载完后立即读该文件,最好关闭后重新打开一次 
f.close() 
  
#关闭FTP客户端连接
ftp.close()


###上传文件


#! /usr/bin/env python

from ftplib import FTP

import sys, getpass, os.path

host="218.108.***.***"
username="ybmftp"
password="ybm!***"

localfile="/home/gws/xym/script/duizhang.txt"

remotepath="~/testpayment"

f=FTP(host)

f.login(username, password)

f.cwd(remotepath)

fd=open(localfile,'rb')print os.path.basename(localfile)

#否则,如果参数
pasv 为假则关闭被动传输模式。
#在被动模式打开的情况下,数据的传送由客户机启动,而不是由服务器开始。
#这里要根据不同的服务器配置

ftp.set_pasv(0)

f.storbinary('STOR %s ' % os.path.basename(localfile),fd)

fd.close()
f.quit




Python中的ftplib模块

Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件

FTP的工作流程及基本操作可参考协议RFC959

ftp登陆连接

from ftplib import FTP #加载ftp模块

ftp=FTP() #设置变量ftp.set_debuglevel(2) #打开调试级别2,显示详细信息

ftp.connect("IP","port") #连接的ftp sever和端口

ftp.login("user","password")#连接的用户名,密码

print ftp.getwelcome() #打印出欢迎信息

ftp.cmd("xxx/xxx") #更改远程目录

bufsize=1024 #设置的缓冲区大小

filename="filename.txt" #需要下载的文件

file_handle=open(filename,"wb").write #以写模式在本地打开文件

ftp.retrbinaly("RETR filename.txt",file_handle,bufsize) #接收服务器上文件并写入本地文件
ftp.set_debuglevel(0) #关闭调试模式ftp.quit #退出ftp
ftp相关命令操作
ftp.cwd(pathname) #设置FTP当前操作的路径

ftp.dir() #显示目录下文件信息

ftp.nlst() #获取目录下的文件

ftp.mkd(pathname) #新建远程目录

ftp.pwd() #返回当前所在位置

ftp.rmd(dirname) #删除远程目录

ftp.delete(filename) #删除远程文件ftp.rename(fromname, toname)#将fromname修改名称为toname。

ftp.storbinaly("STOR filename.txt",file_handel,bufsize) #上传目标文件

ftp.retrbinary("RETR filename.txt",file_handel,bufsize)#下载FTP文件

from ftplib import FTP  
      
ftp = FTP()  

timeout = 30 
 
port = 21 
 
ftp.connect('192.168.1.188',port,timeout) # 连接FTP服务器  
ftp.login('UserName','888888') # 登录 
 
print ftp.getwelcome()  # 获得欢迎信息  
 
ftp.cwd('file/test')    # 设置FTP路径  list = ftp.nlst()       # 获得目录列表 
 for name in list:  
    print(name)             # 打印文件名字  
path = 'd:/data/' + name    # 文件保存路径  
f = open(path,'wb')         # 打开要保存文件  
filename = 'RETR ' + name   # 保存FTP文件  
ftp.retrbinary(filename,f.write) # 保存FTP上的文件  
ftp.delete(name)            # 删除FTP文件  
ftp.storbinary('STOR '+filename, open(path, 'rb')) # 上传FTP文件  
ftp.quit()                  # 退出FTP服务器  


import ftplib  
import os  
import socket  
  
HOST = 'ftp.mozilla.org'  
DIRN = 'pub/mozilla.org/webtools'  
FILE = 'bugzilla-3.6.7.tar.gz'  

def main():  
    try:  
        f = ftplib.FTP(HOST)  
    except (socket.error, socket.gaierror):  
        print 'ERROR:cannot reach " %s"' % HOST  
        return  
    print '***Connected to host "%s"' % HOST  
  
    try:  
        f.login()  
    except ftplib.error_perm:  
        print 'ERROR: cannot login anonymously'  
        f.quit()  
        return  
    print '*** Logged in as "anonymously"'  
    try:  
        f.cwd(DIRN)  
    except ftplib.error_perm:  
        print 'ERRORL cannot CD to "%s"' % DIRN  
        f.quit()  
        return  
    print '*** Changed to "%s" folder' % DIRN  
    try:  
        #传一个回调函数给retrbinary() 它在每接收一个二进制数据时都会被调用  
        f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)  
    except ftplib.error_perm:  
        print 'ERROR: cannot read file "%s"' % FILE  
        os.unlink(FILE)  
    else:  
        print '*** Downloaded "%s" to CWD' % FILE  
    f.quit()  
    return  
  if name == 'main':  
    main()  






os.listdir(dirname):列出dirname下的目录和文件
os.getcwd():获得当前工作目录
os.curdir:返回当前目录('.')
os.chdir(dirname):改变工作目录到dirname
os.path.isdir(name):判断name是不是一个目录,name不是目录就返回false
os.path.isfile(name):判断name是不是一个文件,不存在name也返回false
os.path.exists(name):判断是否存在文件或目录name
os.path.getsize(name):获得文件大小,如果name是目录返回0L
os.path.abspath(name):获得绝对路径
os.path.normpath(path):规范path字符串形式
os.path.split(name):分割文件名与目录(事实上,如果你完全使用目录,它也会将最后一个目录作为文件名而分离,同时它不会判断文件或目录是否存在)
os.path.splitext():分离文件名与扩展名
os.path.join(path,name):连接目录与文件名或目录
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路径
os.remove(dir) #dir为要删除的文件夹或者文件路径
os.rmdir(path) #path要删除的目录的路径。需要说明的是,使用os.rmdir删除的目录必须为空目录,否则函数出错。
os.path.getmtime(name) #获取文件的修改时间 
os.stat(path).st_mtime#获取文件的修改时间
os.stat(path).st_ctime #获取文件修改时间
os.path.getctime(name)#获取文件的创建时间 



python中对文件、文件夹的操作需要涉及到os模块和shutil模块。

创建文件:
1) os.mknod("test.txt")       创建空文件
2) open("test.txt",w)           直接打开一个文件,如果文件不存在则创建文件

创建目录:
os.mkdir("file")                   创建目录

复制文件:

shutil.copyfile("oldfile","newfile")       oldfile和newfile都只能是文件
shutil.copy("oldfile","newfile")            oldfile只能是文件夹,newfile可以是文件,也可以是目标目录

复制文件夹:
shutil.copytree("olddir","newdir")        olddir和newdir都只能是目录,且newdir必须不存在

重命名文件(目录)
os.rename("oldname","newname")       文件或目录都是使用这条命令

移动文件(目录)
shutil.move("oldpos","newpos")    

删除文件
os.remove("file")

删除目录
os.rmdir("dir")                   只能删除空目录
shutil.rmtree("dir")            空目录、有内容的目录都可以删  

转换目录
os.chdir("path")                  换路径

判断目标
os.path.exists("goal")          判断目标是否存在
os.path.isdir("goal")             判断目标是否目录
os.path.isfile("goal")            判断目标是否文件 



Python 实现文件复制、删除

import os  
import shutil  
filelist=[]  
rootdir="/home/zoer/aaa"  
filelist=os.listdir(rootdir)  
for f in filelist:  
filepath = os.path.join( rootdir, f )  
    if os.path.isfile(filepath):  
        os.remove(filepath)  
        print filepath+" removed!"  
    elif os.path.isdir(filepath):  
        shutil.rmtree(filepath,True)  
        print "dir "+filepath+" removed!"

    用python实现了一个小型的自动发版本的工具。这个“自动发版本”有点虚, 只是简单地把debug 目录下的配置文件复制到指定目录,把Release下的生成文件复制到同一指定,过滤掉不需要的文件夹(.svn),然后再往这个指定目录添加几个特定的 文件。
    这个是我的第一个python小程序。
    下面就来看其代码的实现。
首先插入必要的库:
 
import os 
import os.path 
import shutil 
import time,  datetime
 
然后就是一大堆功能函数。第一个就是把某一目录下的所有文件复制到指定目录中:
 

def copyFiles(sourceDir,  targetDir): 
   if sourceDir.find(".svn") > 0: 
       return 
   for file in os.listdir(sourceDir): 
       sourceFile = os.path.join(sourceDir,  file) 
       targetFile = os.path.join(targetDir,  file) 
       if os.path.isfile(sourceFile): 
           if not os.path.exists(targetDir):  
               os.makedirs(targetDir)  
           if not os.path.exists(targetFile) or(os.path.exists(targetFile) and (os.path.getsize(targetFile) != os.path.getsize(sourceFile))):  
                   open(targetFile, "wb").write(open(sourceFile, "rb").read()) 
       if os.path.isdir(sourceFile): 
           First_Directory = False 
           copyFiles(sourceFile, targetFile)

 
删除一级目录下的所有文件:
 
def removeFileInFirstDir(targetDir): 
   for file in os.listdir(targetDir): 
       targetFile = os.path.join(targetDir,  file) 
       if os.path.isfile(targetFile): 
           os.remove(targetFile)
 
复制一级目录下的所有文件到指定目录:
 

def coverFiles(sourceDir,  targetDir): 
       for file in os.listdir(sourceDir): 
           sourceFile = os.path.join(sourceDir,  file)
 
           targetFile = os.path.join(targetDir,  file) 

           #cover the files 
           if os.path.isfile(sourceFile): 
               open(targetFile, "wb").write(open(sourceFile, "rb").read())

 
复制指定文件到目录:
 
def moveFileto(sourceDir,  targetDir): 
   shutil.copy(sourceDir,  targetDir)
 
往指定目录写文本文件:
 
def writeVersionInfo(targetDir): 
   open(targetDir, "wb").write("Revison:")
 
返回当前的日期,以便在创建指定目录的时候用:
 

def getCurTime(): 
   nowTime = time.localtime() 
   year = str(nowTime.tm_year) 
   month = str(nowTime.tm_mon) 
   if len(month) < 2: 
       month = '0' + month 
   day =  str(nowTime.tm_yday) 
   if len(day) < 2: 
       day = '0' + day 
   return (year + '-' + month + '-' + day)

 
然后就是主函数的实现了:
 

if  name =="main": 
   print "Start(S) or Quilt(Q) \n" 
   flag = True 
   while (flag): 
       answer = raw_input() 
       if  'Q' == answer: 
           flag = False 
       elif 'S'== answer : 
           formatTime = getCurTime() 
           targetFoldername = "Build " + formatTime + "-01" 
           Target_File_Path += targetFoldername

           copyFiles(Debug_File_Path,   Target_File_Path) 
           removeFileInFirstDir(Target_File_Path) 
           coverFiles(Release_File_Path,  Target_File_Path) 
           moveFileto(Firebird_File_Path,  Target_File_Path) 
           moveFileto(AssistantGui_File_Path,  Target_File_Path) 
           writeVersionInfo(Target_File_Path+"\\ReadMe.txt") 
           print "all sucess" 
       else: 
           print "not the correct command"linux下python脚本判断目录和文件是否存在

if os.path.isdir('E:test'):
   pass
else:
   os.mkdir('E:test')
##os.mkdir() 只会创建一个目录,不可以级联创建

eg2:
if not os.path.exists('E:test'):  ###判断文件是否存在,返回布尔值
   os.makedirs('E:test')
##os.makedirs() 这个连同中间的目录都会创建,类似于参数mkdir -p

eg3:
try:
   fp = open("file_path")
catch exception:                 except 和catch的区别?
   os.mkdir('file_path') ##os.mkdir() 只会创建一个目录,不可级联创建,但要有异常处理的意识
   fp = open("file_path"
eg4:实测
#!/usr/bin/env python
import os
FILE_PATH='/home/wuxy/aaa111/222/333/444.txt'  ###444.txt 不会当做文件,而是当做目录
if os.path.exists('FILE_PATH'):   ##目录存在,返回为真
        print 'dir not exists'
        os.makedirs(FILE_PATH)   ###FILE_PATH不用加引号。否则会报错
else:
        print 'dir exists'




python实现ftp上传下载文件

#!/usr/bin/env python
# encoding: utf-8
author = "pwy"
'''
上传:上传文件并备份到其他目录
下载:下载文件,并删除远端文件
'''
from ftplib import FTP
from time import sleep
import os,datetime,logging
from shutil import move
 
HOST = "192.168.1.221"
USER = "sxit"
PASSWORD = "1qaz!QAZ"
#PORT = ""
 
#Upload the file, change the directory
remotedir = "/home/test/"
localdir = "/home/sxit/object/"
bakdir = "/home/sxit/bak"
#Download the file, change the directory
Remoredir = "/home/sxit/object1/"
Localdir = "/root/ftp-logging"
 
LOGFILE = datetime.datetime.now().strftime('%Y-%m-%d')+'.log'
 
logging.basicConfig(level=logging.INFO,
        format='%(asctime)s %(filename)s %(levelname)s %(message)s',
        # datefmt='%a, %d %b %Y %H:%M:%S',
        filename= LOGFILE,
        filemode='a')
logging.FileHandler(LOGFILE)
 class CLASS_FTP:
    def init(self,HOST,USER,PASSWORD,PORT='21'):
        self.HOST = HOST
        self.USER = USER
        self.PASSWORD = PASSWORD
        self.PORT = PORT
        self.ftp=FTP()
        self.flag=0     # 0:no connected, 1: connting
 
    def Connect(self):
        try:
            if self.flag == 1:
                logging.info("ftp Has been connected")
            else:
                self.ftp.connect(self.HOST,self.PORT)
                self.ftp.login(self.USER,self.PASSWORD)
                # self.ftp.set_pasv(False)
                self.ftp.set_debuglevel(0)
                self.flag=1
        except Exception:
            logging.info("FTP login failed")
 
    def Up_load(self,remotedir,localdir,bakdir):
        try:
            self.ftp.cwd(remotedir)
            for i in os.listdir(localdir):
                if i.endswith('.txt'):
                    file_handler = open(i,'rb')
                    self.ftp.storbinary('STOR %s' % i,file_handler)
                    logging.info("%s already upload ."%i)
                    try:
                        if os.path.isdir(bakdir):
                            move(i,bakdir)
                            logging.info("%s move to %s ." % (i,bakdir))
                        else:
                            print "Move the file FAILED"
                            logging.info("Move the %s to %s FAILED!"%(i,bakdir))
 
                    except Exception:
                        logging.info("ftp delete file faild !!!!!")
                    file_handler.close()
            # self.ftp.quit()
        except Exception:
            logging.info("Up_load failed")
 
    def Down_load(self,Remoredir,Localdir):
        try:
            self.ftp.cwd(Remoredir)
            for i in self.ftp.nlst():
                if i.endswith('.NET'):   #match file
                    file_handler = open(i,'wb')
                    self.ftp.retrbinary('RETR %s' % i,file_handler.write)
                    logging.info("%s already down ."%i)
                    try:
                        self.ftp.delete(i)
                        logging.info("%s already deleted!"%i)
                    except Exception:
                        logging.info("ftp delete file faild !!!!!")
                    file_handler.close()
            #self.ftp.quit()
        except Exception:
            logging.info("Down_load failed")
 
 
if name == 'main':
    ftp = CLASS_FTP(HOST,USER,PASSWORD)
 
    while True:
        ftp.Connect()
        # ftp.Down_load(Remoredir,Localdir)
        ftp.Up_load(remotedir,localdir,bakdir)
        sleep(30)常用函数用手册查看,以下只是简略,因为没用用到,[待整理]:

login(user='',passwd='', acct='')     登录到FTP 服务器,所有的参数都是可选的
pwd()                       当前工作目录
cwd(path)                   把当前工作目录设置为path
dir([path[,...[,cb]])       显示path 目录里的内容,可选的参数cb 是一个回调函数,会被传给retrlines()方法
nlst([path[,...])           与dir()类似,但返回一个文件名的列表,而不是显示这些文件名
retrlines(cmd [, cb])       给定FTP 命令(如“RETR filename”),用于下载文本文件。可选的回调函数cb 用于处理文件的每一行
retrbinary(cmd, cb[,bs=8192[, ra]])     与retrlines()类似,只是这个指令处理二进制文件。回调函数cb 用于处理每一块(块大小默认为8K)下载的数据。
storlines(cmd, f)   给定FTP 命令(如“STOR filename”),以上传文本文件。要给定一个文件对象f
storbinary(cmd, f[,bs=8192])    与storlines()类似,只是这个指令处理二进制文件。要给定一个文件对象f,上传块大小bs 默认为8Kbs=8192])
rename(old, new)    把远程文件old 改名为new
delete(path)     删除位于path 的远程文件
mkd(directory)  创建远程目录





ftp
 
'''第一个例子'''
def get_C(self,target_dir=None):
        C = []
        print "PWD:", self.ftp.pwd()
        if target_dir is not None:
            self.ftp.cwd(target_dir)# change working directory to target_dir
        server_file_list = []
        fuck_callback = lambda x: (server_file_list.append(x))
        self.ftp.retrlines('LIST', fuck_callback)
        # print server_file_list
        server_file_items = self.filter_dir_list(server_file_list)
        for item in server_file_items:
            if item.is_dir:
                print 'name = ', item.name
                sub_C = self.get_C(item.name)
                # sub_C = ['/'+item.name+'/'+cc.name for cc in sub_C]
                for cc in sub_C:
                    cc.name = '/' + item.name + cc.name
                    print 'name --- ',cc.name
                C.extend(sub_C)
            else:
                item.name = '/' + item.name
                C.append(item)
        self.ftp.cwd('..')
        return C
 
def runtest(self,next_dir):
        C = ftp.get_C(next_dir)
        next_dir2=next_dir[2:]
        C = [cc.pack for cc in C]
        for i in C:
            print i
            next_dir1=i
            pos=next_dir1.rindex('/')
            next_dir3= next_dir1[0:pos]
            all_path=next_dir2 + next_dir3
            print all_path
            next_dir_local = all_path.decode('utf8').encode('gbk')
            try:
                print next_dir_local
                #os.makedirs(next_dir_local)
            except OSError:
                pass
            #os.chdir(next_dir_local)
            localfile=next_dir1[pos+1:]
            print localfile
            allall_path=all_path + "/" + localfile
            self.ftp.cwd('/')
            print self.ftp.pwd()
            #file_handler = open(localfile, 'wb')
            #self.ftp.retrbinary('RETR %s' % (allall_path), file_handler.write)
            #file_handler.close()
 
'''第一个例子获取成/home/user/test.txt这样的列表'''
 
 
第二个例子
def download_files(self, localdir='./', remotedir='./'):
        try:
            self.ftp.cwd(remotedir)
        except:
            debug_print('目录%s不存在,继续...' % remotedir)
            return
        if not os.path.isdir(localdir):
            pass
            #os.makedirs(localdir)
        debug_print('切换至目录 %s' % self.ftp.pwd())
        self.file_list = []
        self.ftp.dir(self.get_file_list)
        remotenames = self.file_list
        print(remotenames)
        # return
        for item in remotenames:
            filetype = item[0]
            filename = item[1]
            print "filename:",filename
            local = os.path.join(localdir, filename)
            if filetype == 'd':
                self.download_files(local, filename)
            elif filetype == '-':
                self.download_file(local, filename)
        self.ftp.cwd('..')
        debug_print('返回上层目录 %s' % self.ftp.pwd())
 
f.download_files(rootdir_local, rootdir_remote)
 
'''第二个例子'''

sftp
 
s_file =  path.join(path_name,name).replace('\\','/')
def process_sftp_dir(path_name):
                """
                此函数递归处理sftp server端的目录和文件,并在client端创建所有不存在的目录,然后针对每个文件在两端的全路径执行get操作.
                path_name第一次的引用值应该是source_path的值
                """
                d_path = path_name.replace(source_path,destination_path,1)
                if not  path.exists(d_path):    # 若目标目录不存在则创建
                    print('%s----Create Local Dir: %s' % (' '*8,d_path))
                    try:
                         makedirs(d_path)    # 递归创建不存在的目录
                    except Exception as err:
                        print('%s----Create %s Failed' % (' '*8,d_path))
                        print('{}----{}'.format(' '*8,err))
                        exit(10)
                for name in (i for i in sftp.listdir(path=path_name) if not i.startswith('.')):
                    """去掉以.开头的文件或目录"""
                    s_file =  path.join(path_name,name).replace('\\','/')    # 在win环境下组合路径所用的'\\'换成'/'
                    d_file = s_file.replace(source_path,destination_path,1)    # 目标端全路径
                    chk_r_path_result = check_remote_path(s_file)
                    if chk_r_path_result == 'file':    # 文件
                        sftp_get(s_file,d_file,12)
                    elif chk_r_path_result == 'directory':    # 目录
                        process_sftp_dir(s_file)    # 递归调用本身
            process_sftp_dir(source_path)




区别很大
ftp:
ftp.retrlines('LIST', fuck_callback)
完全是循环,目录的进行循环操作,而文件下载。最底层目录的文件下载完,回归上级目录。继续循环。

self.ftp.pwd()
self.ftp.dir(self.get_file_list)
get_file_list(self, line)
self.ftp.cwd('..')
self.ftp.cwd(remotedir)
self.download_file(local, filename)
建立好本地目录,然后cd到远程目录,下载

sftp:
sftp.listdir
s_file =  path.join(path_name,name).replace('\\','/') 
指定源全路径下载

代码格式乱了,详细例子

ftp 第一个例子


# !/usr/bin/env python
# -*-coding:utf-8-*-
from ftplib import FTP
from time import sleep
import os, datetime,logging,time
import string,re
d1 = datetime.datetime.now()
'''months=['Jan','Feb','March','Apr','May','Jun','Jul','Aug','Sep']
patternm = r'2017.*|201611.*|201612.*|201610.*'
patternxml = r'.*2016'
patternx = r'xx.*'''''
HOST = "192.168.1.100"
USER = "ftpuser3"
PASSWORD = "test1passwd"
 
class Myfile(object):
    def init(self, name, size, mtime):
        self.name = name  # 文件名字
 
        self.mtime = mtime  # 文件创建时间
        self.is_dir = False   # 是否为文件夹,默认为不是文件夹
 
        #self.size = float(size) / (1024 * 1024)  # 文件大小
        size = float(size)
        if size > 1024*1024:
            self.size = str('%.2f'%(size / (1024*1024))) + 'MB'
        elif size > 1024:
            self.size = str('%.2f'%(size / 1024)) + 'KB'
        else:
            self.size = str(size) + 'Bytes'
    @property
    def is_file(self):
        return not self.is_dir
 
    @property
    def dir_property(self):
        if self.is_dir==True:
            return 'dir'
        return 'file'
 
    def show(self):
        print '[%s], [%s], [%s], [%s]' % (self.name, self.size, self.mtime, self.dir_property)
 
    @property
    def pack(self):
        """
        将myfile对象封装为一个字符串
        :return:
        """
        #return '[%s][%s][%s]'%(self.name, self.size, self.mtime)
        #return '[%s][%s]'%(self.name, self.size)
        return '%s' %(self.name)
 
class CLASS_FTP:
    def init(self, HOST, USER, PASSWORD, PORT='21'):
        self.HOST = HOST
        self.USER = USER
        self.PASSWORD = PASSWORD
        self.PORT = PORT
        self.ftp = FTP()
        self.flag = 0  # 0:no connected, 1: connting
 
    def Connect(self):
        try:
            if self.flag == 1:
                logging.info("ftp Has been connected")
            else:
                self.ftp.connect(self.HOST, self.PORT)
                self.ftp.login(self.USER, self.PASSWORD)
                # self.ftp.set_pasv(False)
                self.ftp.set_debuglevel(0)
                self.flag = 1
        except Exception:
            logging.info("FTP login failed")
 
    def str_codec_std(self,mystr):
        return mystr.decode('utf8').encode('gbk')
 
    def dirmakedirs(self,next_dir_local,local_dir):
        # next_dir_local2= next_dir_local.split('/')[1:]
        next_dir_local2 = next_dir_local[1:].replace('/', '\\')
        # next_dir_localw = next_dir_local2.decode('utf8').encode('gbk')  # windows用这个
        s_file = os.path.join(local_dir, next_dir_local2)
        print "s_file", s_file
        if not os.path.exists(s_file):
            try:
                os.makedirs(s_file)
            except OSError:
                pass
        os.chdir(s_file)
 
    def filter_dir_list(self,mystr_list):
        res = []
        for mystr in mystr_list:
            #mystr = self.str_codec_std(mystr)
            # print "mystr is :%s" % mystr
            file_info = string.split(mystr, maxsplit=8)
            name = file_info[8]
            print 'name = ', name
            if name == '.' or name == '..':
                continue 
            size = file_info[4]
            mtime = '%s-%s-%s' % (file_info[5], file_info[6], file_info[7])
 
            myfile = Myfile(name=name, size=size, mtime=mtime)
 
            dir_info = file_info[0]
            if dir_info[0] == 'd':
                myfile.is_dir = True
            res.append(myfile)
        return res
 
 
    def get_C(self,target_dir=None,local_dir=None):
        C = []
        if target_dir is not None:
            self.ftp.cwd(target_dir)# change working directory to target_dir
        server_file_list = []
        fuck_callback = lambda x: (server_file_list.append(x))
        self.ftp.retrlines('LIST', fuck_callback)
        next_dir_local = self.ftp.pwd()
        self.dirmakedirs(next_dir_local, local_dir)
 
        server_file_items = self.filter_dir_list(server_file_list)
        for item in server_file_items:
            if item.is_dir:
                sub_C = self.get_C(item.name,local_dir)
                for cc in sub_C:
                    cc.name = '/' + item.name + cc.name
                C.extend(sub_C)
            else:
                item.name = '/' + item.name
                C.append(item)
        self.ftp.cwd('..')
        return C
    def runtest(self,local_dir,next_dir):
        os.chdir(local_dir)
        C = ftp.get_C(next_dir,local_dir)
        next_dir2=next_dir[2:]
        C = [cc.pack for cc in C]
        print "C:",C
        for i in C:
            next_dir1=i
            pos=next_dir1.rindex('/')
            next_dir3= next_dir1[0:pos]
            all_path=next_dir2 + next_dir3
 
            self.dirmakedirs(all_path, local_dir)
            next_dir_localz = all_path[1:].replace('/', '\\')
            '''# next_dir_local = next_dir_localz
            # next_dir_local = next_dir_localz.decode('utf8').encode('gbk') #windows用这个'''
            # s_file = os.path.join(local_dir, next_dir_localz)
            # try:
            #     os.makedirs(s_file)
            # except OSError:
            #     pass
            # os.chdir(s_file)
 
            localfile=next_dir1[pos+1:]
            print localfile
            allall_path=all_path + "/" + localfile
            file_handler = open(localfile, 'wb')
            self.ftp.retrbinary('RETR %s' % (allall_path), file_handler.write)
            file_handler.close()
 
if name == 'main':
    ftp = CLASS_FTP(HOST, USER, PASSWORD)
    ftp.Connect()
    ftp.runtest('D:\\ftp','./')
    d2 = datetime.datetime.now()
    print d2 - d1
 
'''参数乱七八糟'''



ftp 第二个例子 别人2010写好的


# !/usr/bin/env python
# coding:utf-8
from ftplib import FTP
import os, sys, string, datetime, time
import socket
 
 
class MYFTP:
    def init(self, hostaddr, username, password, remotedir, port=21):
        self.hostaddr = hostaddr
        self.username = username
        self.password = password
        self.remotedir = remotedir
        self.port = port
        self.ftp = FTP()
        self.file_list = []
        # self.ftp.set_debuglevel(2)
 
    def del(self):
        self.ftp.close()
        # self.ftp.set_debuglevel(0)
 
    def login(self):
        ftp = self.ftp
        try:
            timeout = 60
            socket.setdefaulttimeout(timeout)
            ftp.set_pasv(True)
            print '开始连接到 %s' % (self.hostaddr)
            ftp.connect(self.hostaddr, self.port)
            print '成功连接到 %s' % (self.hostaddr)
            print '开始登录到 %s' % (self.hostaddr)
            ftp.login(self.username, self.password)
            print '成功登录到 %s' % (self.hostaddr)
            debug_print(ftp.getwelcome())
        except Exception:
            deal_error("连接或登录失败")
        try:
            print "now:",self.ftp.pwd()
            self.ftp.cwd(self.remotedir)
        except(Exception):
            deal_error('切换目录失败')
 
    def is_same_size(self, localfile, remotefile):
        try:
            remotefile_size = self.ftp.size(remotefile)
        except:
            remotefile_size = -1
        try:
            localfile_size = os.path.getsize(localfile)
        except:
            localfile_size = -1
        debug_print('lo:%d  re:%d' % (localfile_size, remotefile_size), )
        if remotefile_size == localfile_size:
            return 1
        else:
            return 0
 
    def download_file(self, localfile, remotefile):
        if self.is_same_size(localfile, remotefile):
            debug_print('%s 文件大小相同,无需下载' % localfile)
            return
        else:
            print "remotefile:",remotefile
            debug_print('>>>>>>>>>>>>下载文件 %s ... ...' % localfile)
            # return
        file_handler = open(localfile, 'wb')
        self.ftp.retrbinary('RETR %s' % (remotefile), file_handler.write)
        file_handler.close()
 
    def download_files(self, localdir='./', remotedir='./'):
        try:
            print "remotedir:",remotedir
            self.ftp.cwd(remotedir)
        except:
            debug_print('目录%s不存在,继续...' % remotedir)
            return
        if not os.path.isdir(localdir):
            # pass
            os.makedirs(localdir)
        debug_print('切换至目录 %s' % self.ftp.pwd())
        self.file_list = []
        print(self.ftp.dir())
        self.ftp.dir(self.get_file_list)
        remotenames = self.file_list
        # print(remotenames)
        # return
        for item in remotenames:
            filetype = item[0]
            filename = item[1]
            print "filename:",filename
            local = os.path.join(localdir, filename).replace('\\', '/')
 
            if filetype == 'd':
                self.download_files(local, filename)
            elif filetype == '-':
                self.download_file(local, filename)
        self.ftp.cwd('..')
        debug_print('返回上层目录 %s' % self.ftp.pwd())
 
    def upload_file(self, localfile, remotefile):
        if not os.path.isfile(localfile):
            return
        if self.is_same_size(localfile, remotefile):
            debug_print('跳过[相等]: %s' % localfile)
            return
        file_handler = open(localfile, 'rb')
        self.ftp.storbinary('STOR %s' % remotefile, file_handler)
        file_handler.close()
        debug_print('已传送: %s' % localfile)
 
    def upload_files(self, localdir='./', remotedir='./'):
        if not os.path.isdir(localdir):
            return
        localnames = os.listdir(localdir)
        self.ftp.cwd(remotedir)
        for item in localnames:
            src = os.path.join(localdir, item)
            if os.path.isdir(src):
                try:
                    self.ftp.mkd(item)
                except:
                    debug_print('目录已存在 %s' % item)
                self.upload_files(src, item)
            else:
                self.upload_file(src, item)
        self.ftp.cwd('..')
 
    def get_file_list(self, line):
        print "line1:", line
        ret_arr = []
        file_arr = self.get_filename(line)
        print "file_arr:",file_arr
        if file_arr[1] not in ['.', '..']:
            self.file_list.append(file_arr)
 
    def get_filename(self, line):
        print "line2:",line
        print type(line)
        pos = line.rfind(':')
        while (line[pos] != ' '):
            pos += 1
        while (line[pos] == ' '):
            pos += 1
        print pos
        file_arr = [line[0], line[pos:]]
        return file_arr
 
 
def debug_print(s):
    print (s)
 
 
def deal_error(e):
    timenow = time.localtime()
    datenow = time.strftime('%Y-%m-%d', timenow)
    logstr = '%s 发生错误: %s' % (datenow, e)
    debug_print(logstr)
    file.write(logstr)
    sys.exit()
 
 
if name == 'main':
    file = open("log.txt", "a")
    timenow = time.localtime()
    datenow = time.strftime('%Y-%m-%d', timenow)
    logstr = datenow
    # 配置如下变量
    hostaddr = '192.168.1.100'  # ftp地址
    username = 'ftpuser3'  # 用户名
    password = 'test1passwd'  # 密码
 
 
    port = 21  # 端口号
    #rootdir_local = '.' + os.sep + 'bak/'  # 本地目录
    rootdir_local = 'D:/ftp/'
    rootdir_remote = './'  # 远程目录
 
    f = MYFTP(hostaddr, username, password, rootdir_remote, port)
    f.login()
    f.download_files(rootdir_local, rootdir_remote)
 
    timenow = time.localtime()
    datenow = time.strftime('%Y-%m-%d', timenow)
    logstr += " - %s 成功执行了备份\n" % datenow
    debug_print(logstr)
 
    file.write(logstr)
    file.close()

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 序列化
Python 序列化

本专题整合了python序列化、反序列化相关内容,阅读专题下面的文章了解更多详细内容。

12

2026.02.02

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

200

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

98

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

15

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

16

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

9

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

56

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

28

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号