33

我正在使用 Python 并尝试连接到 SFTP 并希望从那里检索 XML 文件,并且需要将其放置在我的本地系统中。下面是代码:

import paramiko

sftpURL   =  'sftp.somewebsite.com'
sftpUser  =  'user_name'
sftpPass  =  'password'

ssh = paramiko.SSHClient()
# automatically add keys without requiring human intervention
ssh.set_missing_host_key_policy( paramiko.AutoAddPolicy() )

ssh.connect(sftpURL, username=sftpUser, password=sftpPass)

ftp = ssh.open_sftp()
files = ftp.listdir()
print files

这里连接是成功的。现在我想查看所有文件夹和所有文件,并且需要进入所需文件夹以从那里检索 XML 文件。

最后,我的意图是在连接到 SFTP 服务器后查看所有文件夹和文件。

在上面我使用ftp.listdir()过的代码中,我得到了如下所示的输出

['.bash_logout', '.bash_profile', '.bashrc', '.mozilla', 'testfile_248.xml']

我想知道这些是否是唯一存在的文件?

我上面使用的命令也可以查看文件夹吗?

查看所有文件夹和文件的命令是什么?

4

3 回答 3

24

SFTPClient.listdir返回所有内容、文件和文件夹。

是否有文件夹,从文件中告诉他们,SFTPClient.listdir_attr改为使用。它返回一个集合SFTPAttributes

from stat import S_ISDIR, S_ISREG
for entry in sftp.listdir_attr(remotedir):
    mode = entry.st_mode
    if S_ISDIR(mode):
        print(entry.filename + " is folder")
    elif S_ISREG(mode):
        print(entry.filename + " is file")

@Oz123 接受的答案效率低下。SFTPClient.listdir内部调用SFTPClient.listdir_attr并丢弃大部分信息,仅返回文件和文件夹名称。SFTPClient.lstat然后,答案会通过调用每个文件来无用且费力地重新检索所有数据。

另请参阅如何通过 Paramiko 获取目录中所有 SFTP 文件的大小


强制性警告:请勿使用-这样做AutoAddPolicy会失去对MITM 攻击的保护。有关正确的解决方案,请参阅Paramiko "Unknown Server"

于 2019-08-28T14:17:39.843 回答
13

一种快速的解决方案是lstat检查ftp.listdir().

这是列出所有目录的方法。

>>> for i in ftp.listdir():
...     lstatout=str(ftp.lstat(i)).split()[0]
...     if 'd' in lstatout: print i, 'is a directory'
... 

文件是相反的搜索:

>>> for i in ftp.listdir():
...     lstatout=str(ftp.lstat(i)).split()[0]
...     if 'd' not in lstatout: print i, 'is a file'
... 
于 2012-09-06T08:22:12.117 回答
3

这是我想出的解决方案。基于https://stackoverflow.com/a/59109706。我的解决方案给出了一个漂亮的输出。

更新我已经稍微修改了它以纳入马丁的建议。isdir现在我的代码与我使用和的初始版本相比相当快listdir

# prefix components:
space =  '    '
branch = '│   '
# pointers:
tee =    '├── '
last =   '└── '

def stringpath(path):
    # just a helper to get string of PosixPath
    return str(path)

from pathlib import Path
from stat import S_ISDIR
def tree_sftp(sftp, path='.', parent='/', prefix=''):
    """
    Loop through files to print it out
    for file in tree_sftp(sftp):
        print(file)
    """
    fullpath = Path(parent, path)
    strpath = stringpath(fullpath)

    dirs = sftp.listdir_attr(strpath)
    pointers = [tee] * (len(dirs) - 1) + [last]
    pdirs = [Path(fullpath, d.filename) for d in dirs]
    sdirs = [stringpath(path) for path in pdirs]

    for pointer, sd, d in zip(pointers, sdirs, dirs):
        yield prefix + pointer + d.filename
        if S_ISDIR(d.st_mode):
            extension = branch if pointer == tee else space
            yield from tree_sftp(sftp, sd, prefix=prefix + extension)

您可以像这样尝试使用pysftp

import pysftp
with pysftp.Connection(HOSTNAME, USERNAME, PASSWORD) as sftp:
    for file in tree_sftp(sftp):
        print(file)

让我知道是否适合您。

于 2021-03-24T12:38:36.160 回答