Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用pysftp递归下载_Python_Sftp_Pysftp - Fatal编程技术网

Python 使用pysftp递归下载

Python 使用pysftp递归下载,python,sftp,pysftp,Python,Sftp,Pysftp,我正在尝试使用以下结构从SFTP获取: main\u目录/ dir1/ 文件1 dir2/ 文件2 我试图通过以下命令实现这一点: sftp.get_r(main_path + dirpath, local_path) 或 本地路径类似于d:/trapped\u files/target\u dir,远程路径类似于/data/some\u dir/target\u dir 使用get\r我将获得FileNotFound异常。使用get_d我得到的是空目录(当目标目录有文件而不是目录时,它工作

我正在尝试使用以下结构从SFTP获取:

main\u目录/
dir1/
文件1
dir2/
文件2
我试图通过以下命令实现这一点:

sftp.get_r(main_path + dirpath, local_path)

本地路径类似于
d:/trapped\u files/target\u dir
,远程路径类似于
/data/some\u dir/target\u dir

使用
get\r
我将获得
FileNotFound
异常。使用
get_d
我得到的是空目录(当目标目录有文件而不是目录时,它工作正常)


我完全确定这个路径上存在目录。我做错了什么?

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

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)

如果您希望在pysftp周围有一个上下文管理器包装器来为您实现这一点,那么这里有一个解决方案,它的代码更少(在您复制/粘贴github gist之后),在使用时看起来就像下面这样

path = "sftp://user:p@ssw0rd@test.com/path/to/file.txt"

# Read a file
with open_sftp(path) as f:
    s = f.read() 
print s

# Write to a file
with open_sftp(path, mode='w') as f:
    f.write("Some content.") 
(更完整的)示例:

当您第一次无法连接时,这个上下文管理器恰好有自动重试逻辑(这比您在生产环境中预期的要频繁得多)

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


open_sftp的上下文管理器要点:

这一个对我有用,但当你下载目录时,它会在本地创建完整路径

pysftp.Connection.get_r()
我还创建了简单的
下载
上传
方法:

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.')

有关它为什么不适用于您的可能解释,请参阅。
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.')