python ftp

2023-01-31 02:01:36 python ftp
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)

'''第二个例子'''

区别很大

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到远程目录,下载


代码格式乱了,详细例子

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


相关文章