我正在使用 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']
我想知道这些是否是唯一存在的文件?
我上面使用的命令也可以正确查看文件夹吗?
查看所有文件夹和文件的命令是什么?
SFTPClient.listdir
返回所有内容、文件和文件夹。
SFTPClient.listdir_attr
代替。它返回 SFTPAttributes
的集合。
from stat import S_ISDIR, S_ISREG
sftp = ssh.open_sftp()
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“未知服务器”
一个快速解决方案是检查
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'
...
这是我想出的解决方案。基于 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)
让我知道是否适合您。