• python sftp ftp 造轮子,实现多个方法


    SFTP 与 FTP

    python中对于sftp与ftp的支持较少,很多方法都没有,如makedirs与exists检查,只能自己造轮子了,废话不多说,直接上代码。

    class SFTP_obj

    import paramiko
    import os
    import time
    
    
    
    class SFTP_obj():
    
        def action_try(fun):
            def wrapper(*args, **kwargs):  # def 与 return 之后的函数名称一致
                try:
                    ret = fun(*args, **kwargs)
                    return ret  # return ret 与 ret=func(*args,**kwargs)一致
                except Exception as error:
                    print('函数 ' + fun.__name__ + ' 操作失败',end='    ')
                    print(error)
                    #print(traceback.print_exc())
                    #print('函数'+fun.__name__+'操作失败')
            return wrapper
    
        def __init__(self, host, username, password):
            self.host = host
            self.username = username
            self.password = password
            self.connect()
    
        def connect(self):
            ssh = paramiko.SSHClient()
            # automatically add keys without requiring human intervention
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(self.host, username=self.username, password=self.password)
            tr = ssh.get_transport()
            tr.default_max_packet_size = 100000000
            tr.default_window_size = 100000000
            self.sftp = ssh.open_sftp()
            time.sleep(1)
            print('open connect')
    
        def close(self):
            self.sftp.close()
            time.sleep(2)
            print('close connect')
    
    
        # 下载文件
        @action_try
        def downloadfile(self,remotepath, localpath):
            self.sftp.close()
            self.connect()
            print('开始下载 '+ remotepath)
            try:
                self.sftp.get(remotepath,localpath)
                print('下载文件 ' + remotepath + '成功')
                return '1'
            except:
                print('下载文件 ' + remotepath + '失败')
                if os.path.exists(localpath):
                    os.remove(localpath)
                return '0'
            finally:
                self.close()
    
    
        # list文件夹
        @action_try
        def listdir(self, remotepath):
            path_list=[]
            list=self.sftp.listdir(remotepath)
            for name in list:
                path_list.append(os.path.join(remotepath,name))
            return path_list
    
        # 递归遍历得到当前目录下所有的文件路径
        @action_try
        def get_filepaths(self, remotepath,dir_paths=[],file_paths=[]):
            path_list = self.listdir(remotepath)
            for path in path_list:
                #判断是否为文件
                if 'd' not in str(self.sftp.lstat(path)).split()[0]:
                    file_paths.append(path)
                #如果为文件夹
                else:
                    dir_paths.append(path)
                    self.get_filepaths(path,dir_paths,file_paths)
            return  dir_paths,file_paths
    
    
        #同步更新sftp,遍历下载文件到本地,同时创建与sftp相同的文件夹目录
        @action_try
        def downloadfilelist(self,remotepath):
    
            upnumber = 0
            dirslist, fileslist = self.get_filepaths(remotepath)
    
            all_path = dirslist + fileslist
            uplist = []
            for path in all_path:
                localpath = os.path.join('./test', path.strip('/'))
                if not os.path.exists(localpath):
                    uplist.append(localpath)
            print('本次需要更新 ' + str(len(uplist)) + ' 个文件')
    
            for dir in dirslist:
                #print(dir)
                localpath = os.path.join('./test', dir.strip('/'))
                if not os.path.exists(localpath):
                    os.makedirs(localpath)
                    upnumber = upnumber + 1
                else:
                    pass
                    print('目录 ' + dir + ' 已存在,跳过下载')
    
            for file in fileslist:
                #print(file)
                localpath = os.path.join('./test', file.strip('/'))
                if not os.path.exists(localpath):
                    if not os.path.exists(os.path.dirname(localpath)):
                        os.makedirs(os.path.dirname(localpath))
                    flag=self.downloadfile(file, localpath)
                    #假文件
                    # os.mknod(localpath)
                    if flag=='1':
                        upnumber = upnumber + 1
                else:
                    pass
                    print('文件 ' + file + ' 已存在,跳过下载')
    
            print('************************************')
            print('更新 ' + remotepath + ' 成功')
            print('本次更新了 ' + str(upnumber) + ' 个文件')
            print('************************************')
    
    
    
    if __name__=="__main__":
        host = 'xxxx'
        username = 'xxxx'
        password = 'xxxx'
        s=SFTP_obj(host,username,password)

    class FTP_obj

    #-*- coding:utf-8 -*-
    import ftplib
    from ftplib import FTP
    import traceback
    import os
    
    class FTP_obj():
    
        def action_try(fun):
            def wrapper(*args, **kwargs):  # def 与 return 之后的函数名称一致
                try:
                    ret = fun(*args, **kwargs)
                    return ret  # return ret 与 ret=func(*args,**kwargs)一致
                except Exception as error:
                    print('函数' + fun.__name__ + '操作失败',end='    ')
                    print(error)
                    #print(traceback.print_exc())
                    #print('函数'+fun.__name__+'操作失败')
            return wrapper
    
    
        def __init__(self,host,username,password):
            self.ftp = FTP()
            # ftp.set_debuglevel(2)         #打开调试级别2,显示详细信息
            self.ftp.connect(host, 21)  # 连接
            self.ftp.login(username, password)  # 登录,如果匿名登录则用空串代替即可
    
        # 下载文件
        @action_try
        def downloadfile(self,remotepath, localpath):
            bufsize = 1024  # 设置缓冲块大小
            fp = open(localpath, 'wb')  # 以写模式在本地打开文件
            self.ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize)  # 接收服务器上文件并写入本地文件
            self.ftp.set_debuglevel(0)  # 关闭调试
            print('下载文件' + remotepath + '成功')
            fp.close()  # 关闭文件
    
        #上传文件
        @action_try
        def uploadfile(self,remotepath, localpath):
            bufsize = 1024
            fp = open(localpath, 'rb')
            self.ftp.storbinary('STOR ' + remotepath, fp, bufsize)  # 上传文件
            self.ftp.set_debuglevel(0)
            print('上传文件' + remotepath + '成功')
            fp.close()
    
        #删除文件
        @action_try
        def delete(self,remotepath):
            self.ftp.delete(remotepath)
            print('删除文件' + remotepath + '成功')
    
        #创建文件夹
        def mkdir(self,remotepath):
            self.ftp.mkd(remotepath)
            print('创建文件夹' + remotepath + '成功')
    
        # 删除文件夹
        @action_try
        def dldir(self, remotepath):
            self.ftp.rmd(remotepath)
            print('删除文件夹' + remotepath + '成功')
    
        #list文件夹
        @action_try
        def listdir(self, remotepath):
            list = self.ftp.nlst(remotepath)
            return list
    
    
        #得到本地需要更新的所有文件路径
        def get_local_paths(self,local,dir_paths=[],file_paths=[]):
            path_list = os.listdir(local)
            for path in path_list:
                path=os.path.join(local,path)
                # 判断是否为文件
                if os.path.isfile(path):
                    file_paths.append(path)
                # 如果为文件夹
                else:
                    dir_paths.append(path)
                    self.get_local_paths(path, dir_paths, file_paths)
            return dir_paths, file_paths
    
        # 将本地目标文件夹所有内容全部上传ftp
        def upload_all_files(self,local):
            upnumber=0
            dirslist, fileslist = self.get_local_paths(local)
    
            all_path = dirslist + fileslist
            uplist = []
            for path in all_path:
                print(path)
                ftppath = os.path.join('/XXXX_image/', path.replace('/home/ts/下载/huilin_ftp/',''))
                if self.check(ftppath)=='none':
                    uplist.append(ftppath)
            print('本次需要更新 ' + str(len(uplist)) + ' 个文件')
            print(uplist)
    
            for dir in dirslist:
                #print('****'+dir)
                ftppath = os.path.join('/XXXX_image/', dir.replace('/home/ts/下载/huilin_ftp/',''))
                self.makedirs(ftppath)
    
            for file in fileslist:
                #print(file)
                ftppath = os.path.join('/XXXX_image/', file.replace('/home/ts/下载/huilin_ftp/',''))
                ftp_dir=os.path.join('/XXXX_image/', os.path.dirname(file).replace('/home/ts/下载/huilin_ftp/',''))
                if self.check(ftppath) != 'file_exists':
                    if self.check(ftp_dir)!='dir_exists':
                        self.makedirs(ftp_dir)
                    self.uploadfile(ftppath,file)
                else:
                    print('文件 '+file+' 已经存在,跳过上传')
    
        #判断路径类型以及是否存在
        def check(self,path):
            type='none'
            try:
                self.ftp.size(path)
                type='file_exists'
            except:
                try:
                    self.ftp.cwd(path)
                    type='dir_exists'
                except:
                    type='none'
            finally:
                return type
    
        #递归创建文件夹
        def makedirs(self, path):
            if self.check(path)=='dir_exists':
                print('文件夹 '+path+' 存在,跳过上传')
            else:
                path_split = path.strip('/').split('/')
                dir_path = '/'
                for item in path_split:
                    dir_path = dir_path + '/' + item
                    if self.check(path)!='dir_exists':
                        try:
                            self.mkdir(dir_path)
                        except:
                            pass
    
    
    
    
    if __name__ == "__main__":
        host='XXXX'
        username='XXXX'
        password='XXXX'
        ftp=FTP_obj(host,username,password)
  • 相关阅读:
    python epoll
    解决linux下/etc/rc.local开机器不执行的原因
    xen4.1.2网桥配置
    用户激励设计[转]
    C#4.0的dynamic和var及object关键字辨析
    动态设置和修改Membership/Profile/RoleProvider的ConnectionString数据库连接字符串
    UseCase用例怎么画_UML用例UseCase的几个理解误区
    C#的delegate/event/Action/Func/Predicate关键字
    我为什么鄙视提倡加班的公司
    [转]个人成长之通关路!
  • 原文地址:https://www.cnblogs.com/CYHISTW/p/14116030.html
Copyright © 2020-2023  润新知