使用多处理和 PySftp 并行下载



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

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)  

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

不要手动检查文件,而是尝试在连接对象上使用walktree方法:pysftp walktree

这是我在Python 3.5中制作的一个工作示例。我只是使用本地ftp服务器和小文件,所以我模拟了下载延迟。更改max_workers参数以设置同时下载的次数。

"""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.

相关内容

  • 没有找到相关文章

最新更新