使用pysftp进行递归下载

时间:2016-11-15 11:24:30

标签: python ftp sftp pysftp

我正在尝试从ftp下一个结构中获取:

= main_dir /

== dir1 /

=== file1

== dir2 /

=== file2

我尝试使用以下命令实现此目的:

sftp.get_r(main_path + dirpath, local_path)

sftp.get_d(main_path + dirpath, local_path)

使用get_r我收到FileNotFound异常。使用get_d我得到空目录(当目标目录没有dirs文件时,它工作正常)。

我完全确定此路径中存在该目录。我究竟做错了什么?

3 个答案:

答案 0 :(得分:0)

我不明白为什么它不起作用所以我以自己的递归解决方案结束了:

def grab_dir_rec(sftp, dirpath):
    local_path = target_path + dirpath
    full_path = main_path + dirpath
    if not sftp.exists(full_path):
        return
    if not os.path.exists(local_path):
        os.makedirs(local_path)

    dirlist = sftp.listdir(remotepath=full_path)
    for i in dirlist:
        if sftp.isdir(full_path + '/' + i):
            grab_dir_rec(sftp, dirpath + '/' + i)
        else:
            grab_file(sftp, dirpath + '/' + i)

答案 1 :(得分:0)

如果您希望pysftp周围的上下文管理器包装器为您执行此操作,这里的解决方案甚至更少(在您复制/粘贴github gist之后),在使用时最终看起来如下所示< / p>

GlobalConfiguration.Configure((config) => { config.MapHttpAttributeRoutes(); });

(更全面)的例子:http://www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

如果你第一次无法连接,这个上下文管理器碰巧有自动重试逻辑(这种情况比你在生产环境中预期的更频繁......)。

哦,是的,这假设您每个连接只获得一个文件,因为它会自动关闭ftp连接。

open_sftp的上下文管理器要点:https://gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515

答案 2 :(得分:0)

这对我有用,但是当您下载目录时,它将在本地创建完整路径。

pysftp.Connection.get_r()

我还创建了简单的downloadupload方法:

def download_r(sftp, outbox):
    tmp_dir = helpers.create_tmpdir()
    assert sftp.isdir(str(outbox))
    assert pathlib.Path(tmp_dir).is_dir()
    sftp.get_r(str(outbox), str(tmp_dir))
    tmp_dir = tmp_dir / outbox
    return tmp_dir


def upload_r(sftp, inbox, files):
    assert sftp.isdir(str(inbox))
    if pathlib.Path(files).is_dir():
        logger.debug(list(files.iterdir()))
        sftp.put_r(str(files), str(inbox))
    else:
        logger.debug('No files here.')