FTP 的递归文件列表
Recursive file list with FTP
我知道如何列出 FTP 服务器目录中的所有文件:
import ftplib
ftp = ftplib.FTP()
ftp.connect("192.168.1.18", port=2240)
ftp.login()
ftp.cwd('path/to')
for f in ftp.mlsd():
print(f)
但是获取递归文件列表(即子目录中的文件、子目录等中的文件)的最佳方法是什么?
即Python 3 的 FTP 的等价物 glob.glob('path/to/**/*', recursive=True)
递归列出所有文件。
我可以通过手动输入每个目录,然后重做 msld()
但我担心这会很慢(据我记得,在 FTP 中列出文件已经很慢了) , 所以这不是最优的。
用 SFTP 怎么做?使用 SFTP 递归列出所有文件会更容易吗?
I could do it by entering manually each dir, and then redo a msld()
这是正确的解决方案。 FTP 协议没有任何更好的 标准 方法来检索递归列表。所以没有 space 进行优化(只能通过并行化操作)。另见 Downloading a directory tree with ftplib。
一些 FTP 服务器支持非标准 -R
开关和一些文件列表命令(不确定 MLSD
)。因此,如果您愿意依赖非标准功能并且您的特定服务器支持它,您可以通过这种方式优化您的代码。另见 。
对于 SFTP,参见
由于 LIST -R
、NLST -R
、MLSD -R
对我不起作用,我遵循 @MartinPrikryl 的建议,这是一个 FTP 解决方案:
import ftplib, time
def list_recursive(ftp, remotedir):
ftp.cwd(remotedir)
for entry in ftp.mlsd():
if entry[1]['type'] == 'dir':
remotepath = remotedir + "/" + entry[0]
print(time.time() - t0, remotepath)
list_recursive(ftp, remotepath)
else:
print(entry)
ftp = ftplib.FTP()
ftp.connect("192.168.1.18", port=2240)
ftp.login()
t0 = time.time()
list_recursive(ftp, '/sdcard/music')
大约 900 个文件夹中的大约 20k 个文件花费了 344 秒(我的 FTP 服务器在 phone: cx 文件资源管理器应用程序上)。
作为对比,下面是SFTP的解决方案:
import pysftp
def list_recursive(sftp, remotedir):
for entry in sftp.listdir_attr(remotedir):
remotepath = remotedir + "/" + entry.filename
if sftp.isdir(remotepath):
print(remotepath)
list_recursive(sftp, remotepath)
else:
print(entry.st_size, entry.st_mtime, entry.filename)
cnopts = pysftp.CnOpts() # for local testing
cnopts.hostkeys = None
with pysftp.Connection('192.168.1.18', port=2222, username='ssh', password='', cnopts=cnopts) as sftp:
list_recursive(sftp, 'music')
大约 900 个文件夹中的大约 20k 个文件花费了 222 秒(我在 Android phone 上使用了 SSH/SFTP 服务器应用程序)。
我知道如何列出 FTP 服务器目录中的所有文件:
import ftplib
ftp = ftplib.FTP()
ftp.connect("192.168.1.18", port=2240)
ftp.login()
ftp.cwd('path/to')
for f in ftp.mlsd():
print(f)
但是获取递归文件列表(即子目录中的文件、子目录等中的文件)的最佳方法是什么?
即Python 3 的 FTP 的等价物 glob.glob('path/to/**/*', recursive=True)
递归列出所有文件。
我可以通过手动输入每个目录,然后重做 msld()
但我担心这会很慢(据我记得,在 FTP 中列出文件已经很慢了) , 所以这不是最优的。
用 SFTP 怎么做?使用 SFTP 递归列出所有文件会更容易吗?
I could do it by entering manually each dir, and then redo a msld()
这是正确的解决方案。 FTP 协议没有任何更好的 标准 方法来检索递归列表。所以没有 space 进行优化(只能通过并行化操作)。另见 Downloading a directory tree with ftplib。
一些 FTP 服务器支持非标准 -R
开关和一些文件列表命令(不确定 MLSD
)。因此,如果您愿意依赖非标准功能并且您的特定服务器支持它,您可以通过这种方式优化您的代码。另见
对于 SFTP,参见
由于 LIST -R
、NLST -R
、MLSD -R
对我不起作用,我遵循 @MartinPrikryl 的建议,这是一个 FTP 解决方案:
import ftplib, time
def list_recursive(ftp, remotedir):
ftp.cwd(remotedir)
for entry in ftp.mlsd():
if entry[1]['type'] == 'dir':
remotepath = remotedir + "/" + entry[0]
print(time.time() - t0, remotepath)
list_recursive(ftp, remotepath)
else:
print(entry)
ftp = ftplib.FTP()
ftp.connect("192.168.1.18", port=2240)
ftp.login()
t0 = time.time()
list_recursive(ftp, '/sdcard/music')
大约 900 个文件夹中的大约 20k 个文件花费了 344 秒(我的 FTP 服务器在 phone: cx 文件资源管理器应用程序上)。
作为对比,下面是SFTP的解决方案:
import pysftp
def list_recursive(sftp, remotedir):
for entry in sftp.listdir_attr(remotedir):
remotepath = remotedir + "/" + entry.filename
if sftp.isdir(remotepath):
print(remotepath)
list_recursive(sftp, remotepath)
else:
print(entry.st_size, entry.st_mtime, entry.filename)
cnopts = pysftp.CnOpts() # for local testing
cnopts.hostkeys = None
with pysftp.Connection('192.168.1.18', port=2222, username='ssh', password='', cnopts=cnopts) as sftp:
list_recursive(sftp, 'music')
大约 900 个文件夹中的大约 20k 个文件花费了 222 秒(我在 Android phone 上使用了 SSH/SFTP 服务器应用程序)。