Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1649219
  • 博文数量: 631
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 3920
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-06 21:58
个人简介

博客是我工作的好帮手,遇到困难就来博客找资料

文章分类

全部博文(631)

文章存档

2022年(2)

2021年(4)

2020年(40)

2019年(4)

2018年(78)

2017年(213)

2016年(41)

2015年(183)

2014年(66)

我的朋友

分类: 系统运维

2017-03-19 20:44:24

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()


阅读(1011) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~