继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

python通过sftp远程传输文件

泛舟湖上清波郎朗
关注TA
已关注
手记 304
粉丝 32
获赞 226

前言

python提供了一个第三方模块paramiko,通过这个模块可以实现两台机器之间的网络连接,sftp是paramiko的一个方法,使用sftp可以在两台机器之间互相传输
拷贝文件。然而paramiko的sftp只能拷贝文件,不能拷贝文件夹。要实现文件夹的拷贝,可以这样子思考:使用深度搜索遍历源目录,若是文件,直接拷贝到
目的目录;若是文件夹,则先在目的目录建立一个子目录,然后遍历子目录...使用递归函数,可以达到完全拷贝目录的目的。实现代码如下:

1.获取一个sftp句柄

import paramiko
#建立连接,获取sftp句柄
def sftp_connect(username,password,host,port=22):
    client = None
    sftp = None
    try:
        client = paramiko.Transport((host,port))
    except Exception as error:
        print error
    else:
        try:
            client.connect(username=username, password=password)
        except Exception as error:
            print error
        else:
            sftp = paramiko.SFTPClient.from_transport(client)
    return client,sftp
#断开连接
def disconnect(client):
    try:
        client.close()
    except Exception as error:
        print error

2.从远程机器上下载文件(夹)到本地

import os
import sys
from stat import S_ISDIR as isdir
def _check_local(local):
    if not os.path.exists(local):
        try:
            os.mkdir(local)
        except IOError as err:
            print err
def get(sftp,remote,local):
    #检查远程文件是否存在
    try:
        result = sftp.stat(remote)
    except IOError as err:
        error = '[ERROR %s] %s: %s' %(err.errno,os.path.basename(os.path.normpath(remote)),err.strerror)
        print error
    else:
        #判断远程文件是否为目录
        if isdir(result.st_mode):
            dirname = os.path.basename(os.path.normpath(remote))
            local = os.path.join(local,dirname)
            _check_local(local)
            for file in sftp.listdir(remote):
                sub_remote = os.path.join(remote,file)
                sub_remote = sub_remote.replace('\\','/')
                get(sftp,sub_remote,local)
        else:   
        #拷贝文件
            if os.path.isdir(local):
                local = os.path.join(local,os.path.basename(remote))
            try:
                sftp.get(remote,local)
            except IOError as err:
                print err
            else:
                print '[get]',local,'<==',remote

3.从本地拷贝文件(夹)到远程机器

import os
def put(sftp,local,remote):
    #检查路径是否存在
    def _is_exists(path,function):
        path = path.replace('\\','/')
        try:
            function(path)
        except Exception as error:
            return False
        else:
            return True
    #拷贝文件
    def _copy(sftp,local,remote):
        #判断remote是否是目录
        if _is_exists(remote,function=sftp.chdir):
            #是,获取local路径中的最后一个文件名拼接到remote中
            filename = os.path.basename(os.path.normpath(local))
            remote = os.path.join(remote,filename).replace('\\','/')
        #如果local为目录
        if os.path.isdir(local):
            #在远程创建相应的目录
            _is_exists(remote,function=sftp.mkdir)
            #遍历local
            for file in os.listdir(local):
                #取得file的全路径
                localfile = os.path.join(local,file).replace('\\','/')
                #深度递归_copy()
                _copy(sftp=sftp,local=localfile,remote=remote)
        #如果local为文件
        if os.path.isfile(local):
            try:
                sftp.put(local,remote)
            except Exception as error:
                print error
                print '[put]',local,'==>',remote,'FAILED'
            else:
                print '[put]',local,'==>',remote,'SUCCESSED'
    #检查local
    if not _is_exists(local,function=os.stat):
        print "'"+local+"': No such file or directory in local"
        return False
    #检查remote的父目录
    remote_parent =  os.path.dirname(os.path.normpath(remote))
    if not _is_exists(remote_parent,function=sftp.chdir):
        print "'"+remote+"': No such file or directory in remote"
        return False
    #拷贝文件
    _copy(sftp=sftp,local=local,remote=remote

)

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP