如何批量下载SFTP服务器不同目录下的指定文件到本地
SFTP分散指定文件高效下载方案
按落地优先级从高到低排列,均不会破坏服务端原有文件结构:
方案1:服务端流式打包下载(效率最高,推荐优先用)
你之前测的单大文件传输速度远高于小文件串行,核心差异是小文件传输存在大量连接协商、目录切换、IO寻址的额外开销,这个方案可以完全消除这类开销,速度和传输同等大小单文件一致。
- 前置要求:你的SFTP账号关联SSH权限,支持执行基础的
tar命令(90%以上的标准SFTP服务默认支持) - 操作步骤:
- 把所有需要下载的文件整理成路径清单,每行一个文件的绝对路径,比如
/IMAGES/folder1/img12,存在本地命名为file_list.txt - 本地执行命令直接拉取打包流,不需要在服务端生成任何临时文件:
cat file_list.txt | ssh sftp账号@SFTP服务器地址 "tar -cf - -T -" > images.tar - 下载完成后本地解包
images.tar即可
- 把所有需要下载的文件整理成路径清单,每行一个文件的绝对路径,比如
- 说明:命令里的
-cf -代表tar把打包结果输出到标准输出流,-T -代表从标准输入读取要打包的文件路径,整个过程tar在服务端顺序读取所有目标文件,字节流直接通过SSH通道传到本地落盘,不会复制原文件、不会修改原目录结构,服务端额外内存、磁盘占用几乎为0。如果是未压缩的位图类文件可以加z参数走gzip压缩,jpg/png等本身已压缩的图像格式加压缩反而会拖慢速度,不建议加。
方案2:硬链接聚合后单目录下载(无SSH执行权限时用)
你之前提到SFTP不支持copy、rename会破坏原结构,但标准SFTP协议支持硬链接操作,完全可以满足聚合需求:
- 前置要求:你在SFTP服务器上有可写目录,且该目录和目标图像在同一个文件系统(硬链接不支持跨文件系统,同盘即可)
- 操作逻辑:
- 在服务端创建一个临时目录,比如
/tmp/your_download_temp - 遍历你要下载的所有目标文件,给每个文件在临时目录创建同名硬链接:
ln 原文件绝对路径 临时目录路径/文件名 - 硬链接创建速度极快,数万文件几秒就能完成,不会额外占用磁盘空间,也不会修改原目录的任何文件——硬链接本质是给同一个文件的inode多建一个目录索引,删除硬链接不会影响原文件
- 直接把整个临时目录下载到本地,下载完成后删除临时目录下所有硬链接即可,原存储结构完全不受影响
- 在服务端创建一个临时目录,比如
- 注意:不要用软链接,SFTP客户端默认不会解析软链接指向的原文件,会直接下载成几字节的链接文件,硬链接和普通文件对客户端来说没有任何区别,下载内容完全一致。
方案3:客户端多并发下载(无服务端写权限、无SSH权限时用)
如果前面两个方案的条件都不满足,就从客户端侧优化,解决串行下载带宽跑不满的问题:
- 核心逻辑:单SFTP连接串行下载小文件时,大部分时间都在等网络往返和服务端IO响应,带宽利用率通常只有10%不到,开10-20个并发连接同时下载不同文件,就能把带宽跑满,速度可以提升5-10倍
- 操作方式:不用手动逐目录下载,用支持并行的SFTP客户端比如
lftp,把所有目标文件路径整理成下载命令列表,设置并行数15-25(不要开太高避免触发服务端限流),自动批量下载即可,示例配置:# 先把所有要下载的文件转成 get 原路径 -o 本地保存路径 的格式存到download_cmd.txt lftp sftp://账号:密码@服务器地址 <<EOF set sftp:connect-program "ssh -a -x" set cmd:parallel 20 set net:max-retries 3 source download_cmd.txt EOF
不建议用第三方GUI客户端的批量下载功能,大部分默认是单线程串行,速度和手动逐个下没有本质区别。
内容的提问来源于stack exchange,提问作者thatGuy
相关产品推荐
相关产品推荐

