首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多处理和PySftp并行下载

多处理和PySftp并行下载
EN

Stack Overflow用户
提问于 2017-08-12 17:48:05
回答 1查看 3.9K关注 0票数 3

我正在尝试使用pysftp和多处理库创建一个代码来下载相同类型的N个文件。我做了一个基本的蟒蛇训练,得到了一些代码,并将它们组合成一个,但我无法完成它。如果有人能帮我的话我会很感激的。错误发生在vFtp.close()命令之后。在应该同时开始下载的部分。

代码语言:javascript
复制
from multiprocessing import Pool
import pysftp
import os

vHost='10.11.12.13'
vLogin='admin'
vPwd='pass1234'
vFtpPath='/export/home/'

os.chdir('d:/test/')
os.getcwd()

cnopts=pysftp.CnOpts()
cnopts.hostkeys = None

vFtp=pysftp.Connection(vHost,username=vLogin,password=vPwd,cnopts=cnopts)
vFtp.cwd(vFtpPath)
vObjectList=vFtp.listdir()
vFileList=[]
vFoldList=[]

for vObject in vObjectList:
    vType=str(vFtp.lstat(vObject))[:1]
    if vType!='d': 
        vFileList.append(vObject)
    else:   
        vFoldList.append(vObject)

vFtp.close()

def fDownload(vFileAux):
    vFtpAux=pysftp.Connection(vHost,username=vLogin,password=vPwd,cnopts=cnopts)
    vFtpAux.cwd(vFtpPath)
    vFtpAux.get(vFileAux,preserve_mtime=True)
    vFtpAux.close()

if __name__ == "__main__":
    vPool=Pool(3)
    vPool.map(fDownload,vFileList)  
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-13 16:39:11

看起来您正在尝试获取文件列表,然后使用多个进程同时下载它们。

不要手动检查文件,而是尝试在connection对象:pysftp步行树上使用pysftp步行树方法

下面是我用Python3.5制作的一个工作示例。我只是使用本地ftp服务器和小文件,所以我模拟了下载延迟。更改max_workers参数以设置同时下载的数量。

代码语言:javascript
复制
"""Demo using sftp to download files simultaneously."""
import pysftp
import os
from concurrent.futures import ProcessPoolExecutor
import time


def do_nothing(s):
    """
    Using this as the callback for directories and unknown items found
    using walktree.
    """
    pass


def download(file):
    """
    Simulates a 1-second download.
    """
    with pysftp.Connection(
            host='convox', username='abc', private_key='/home/abc/test') as sftp:

        time.sleep(1)
        print('Downloading {}'.format(file))
        sftp.get(file)


def get_list_of_files(remote_dir):
    """
    Walks remote directory tree and returns list of files.
    """
    with pysftp.Connection(
            host='convox', username='abc', private_key='/home/abc/test') as sftp:

        files = []

        # if this finds a file it will send the filename to the file callback
        # which in this case just appends to the 'files' list
        sftp.walktree(remote_dir, fcallback=files.append,
                      dcallback=do_nothing, ucallback=do_nothing)

    return files

if __name__ == '__main__':
    remote_dir = '/home/abc/remoteftp/'
    download_target = '/home/abc/localftp/'

    # if you don't specify a localpath in sftp.get then it just downloads to
    # the os cwd, so set it here
    os.chdir(download_target)

    files = get_list_of_files(remote_dir)
    pool = ProcessPoolExecutor(max_workers=4)
    pool.map(download, files)

编辑:ProcessPoolExecutor是用于在多个cpu核上运行一些东西,并且将受到处理器的限制。对于像下载这样的网络任务,您可以使用线程代替。在上面的代码中,这只是一个更改:而不是ProcessPoolExecutor导入和使用ThreadPoolExecutor。然后您可以使用更多的max_workers

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45653213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档