使用paramiko上传和下载sftp数据

paramiko是一个python库,可用于上传和下载sftp数据。这里写一个上传和下载并保持目录结构的方法

上传

从windows到linux

import paramiko
import os

# 递归创建目标Linux系统中的文件夹
def mkdir_p(sftp, remote_directory):
    if remote_directory == '/':
        return
    try:
        sftp.stat(remote_directory)
    except IOError:
        dirname, basename = os.path.split(remote_directory.rstrip('/'))
        mkdir_p(sftp, dirname)
        sftp.mkdir(remote_directory)
    return

def upload(ip, port, username, password, local_folder, remote_folder):
    sf = paramiko.Transport((ip, port))
    sf.connect(username=username, password=password)
    sftp = paramiko.SFTPClient.from_transport(sf)

    local_files = []
    for root, dirs, files in os.walk(local_folder):
        for file in files:
            local_files.append(os.path.join(root, file))
    for file in local_files:
        remote_path = os.path.join(remote_folder, os.path.relpath(file, local_folder)).replace("\\", "/")
        mkdir_p(sftp, os.path.dirname(remote_path))
        print(file.split("\\")[-1] + "  --->  " + remote_path)
        sftp.put(file, remote_path)
    sf.close() 

下载

从linux到windows

import paramiko
import os
import stat
import ntpath

def download_remote_folder(sftpx, remote_folder_path, local_folder_path):
    # 创建本地目录
    if not os.path.exists(local_folder_path):
        os.makedirs(local_folder_path)
    # 列出远程目录文件
    files = sftpx.listdir(remote_folder_path)
    for file in files:
        remote_file_path = os.path.join(remote_folder_path, file).replace('\\', '/')
        local_file_path = os.path.join(local_folder_path, ntpath.basename(file)).replace('\\', '/')
        print(remote_file_path.split("/")[-1] + "  --->  " + local_file_path)
        if stat.S_ISDIR(sftpx.stat(remote_file_path).st_mode):
            # 递归,传递 sftpx 对象作为参数
            download_remote_folder(sftpx, remote_file_path, local_file_path)
        else:
            # 下载
            sftpx.get(remote_file_path, local_file_path)


def download(ip, port, username, password, remote_folder, local_folder):
    sf = paramiko.Transport((ip, port))
    sf.connect(username=username, password=password)
    sftp = paramiko.SFTPClient.from_transport(sf)
    if not os.path.exists(local_folder):
        os.makedirs(local_folder)
    download_remote_folder(sftp, remote_folder, local_folder)
    sf.close()