sftp下载 上传

"""使用paramiko模块中的sftp登陆远程主机,实现上传和下载功能"""

# 根据输入参数判断是文件还是目录,进行上传和下载
# 本地参数local需要与远程参数remote类型一致,文件以文件名结尾,目录以\结尾
# 上传和下载的本地和远程目录需要存在
# 异常捕获


import paramiko
import os
import logging
from stat import S_ISDIR as isdir
import re

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')


class Sftp(object):

    def __init__(self, ip, username, password):
        self.ip = ip
        self.username = username
        self.password = password
        self.sftp = self.connect()

    def connect(self):
        try:
            t = paramiko.Transport((self.ip, 22))  # 创建连接
            # logging.info(self.ip)

            t.connect(username=self.username, password=self.password)
            sftp = paramiko.SFTPClient.from_transport(t)
            return sftp
            # logging.info(self.sftp)
            # return sftp
        except Exception as e:
            logging.info(e)

    # # 获取单个文件
    # def get(self, remotefile, localfile):
    #
    #     self.sftp.get(remotefile, localfile)
    #
    # # 上传单个文件
    # def put(self, localfile, remotefile):
    #
    #     self.sftp.put(localfile, remotefile)

    # 获取目录 所有文件
    def __get_all_file(self, remote_dir):
        all_files = list()

        # 去掉路径字符串最后的字符'/',如果有的话
        if remote_dir[-1] == '/':
            remote_dir = remote_dir[0:-1]

        # 获取当前指定目录下的所有目录及文件,包含属性值
        # logging.info(sftp)
        files = self.sftp.listdir_attr(remote_dir)

        for i in files:
            # 如果是文件 remote_dir目录中的完整路径
            filename = remote_dir + '/' + i.filename
            # logging.info(filename)
            # 如果是目录,递归处理该目录
            if isdir(i.st_mode):
                if not os.path.exists(i.filename):
                    os.makedirs(i.filename)
                all_files.extend(self.__get_all_file(filename))
            else:
                all_files.append(filename)

        return all_files

    def get_dir(self, remote_dir, local_dir):
            all_files = self.__get_all_file(remote_dir)
            for x in all_files:

                filepath = re.split('[:/]', x)
                filename = filepath[-1]
                local_path = local_dir + os.sep + '/'.join(filepath[1:-1])
                if not os.path.exists(local_path):
                    os.makedirs(local_path)
                local_filename = os.path.join(local_path, filename)
                print(u'get文件{}传输中'.format(filename))
                # logging.info(sftp)
                self.sftp.get(x, local_filename)

    def __put_all_file(self, local_dir):
        # 保存所有文件的列表
        all_files = list()
        # 获取当前指定目录下的所有目录及文件 或目录的完整路径
        files = os.listdir(local_dir)
        for i in files:
            # local_dir目录中每一个文件或目录的完整路径
            filename = os.path.join(local_dir, i)
            # 是目录就递归处理
            if os.path.isdir(i):
                all_files.extend(self.__put_all_file(filename))
            else:
                all_files.append(filename)

        return all_files

    def put_dir(self, local_dir, remote_dir):
        # 去掉字符串最后的字符
        if remote_dir[-1] == '/':
            remote_dir = remote_dir[0:-1]
        # 获取本地指定的目录及目录下的文件
        all_files = self.__put_all_file(local_dir)
        for i in all_files:
            filename = os.path.split(i)[-1]
            remote_filename = remote_dir + '/' + filename
            print(u'Put文件{}传输中...'.format(filename))
            self.sftp.put(i, remote_filename)


if __name__ == '__main__':

    remote_path = '/upload'
    local_path = '/home/python/Desktop/'
    host = Sftp('47.104.236.156', 'test', 'test123')
    # 将远端remote_path目录中的所有文件get到本地local_path目录
    host.get_dir(remote_path, local_path)
    # host.put_dir(local_path, remote_path)
 

猜你喜欢

转载自blog.csdn.net/weixin_42020284/article/details/83573363