如何实现HTTP下载大文件不落地存储直接流式上传至FTP服务器
HTTP大文件边下载边上传到FTP的流实现方案
这种流式传输的方案完全可实现,相比先完整下载再上传的模式,不需要占用本地磁盘存储临时文件,总耗时只取决于下载和上传链路的带宽瓶颈,大幅提升大文件传输效率。
核心实现逻辑
- 使用支持流式响应的HTTP客户端请求资源,不一次性加载整个文件到内存或磁盘
- 提前建立FTP连接并开启被动模式(适配绝大多数公网FTP服务端要求)
- 直接将HTTP响应的可读字节流作为FTP上传方法的输入,FTP客户端会按固定分片大小持续从HTTP流中拉取数据上传,全程无本地缓存。
Python实现示例
标准库版本(无需额外安装依赖)
from urllib.request import urlopen from ftplib import FTP def stream_http_to_ftp(http_url, ftp_host, ftp_user, ftp_passwd, ftp_target_path, chunk_size=2*1024*1024): # 初始化FTP连接 ftp = FTP(ftp_host) ftp.login(user=ftp_user, passwd=ftp_passwd) ftp.set_pasv(True) # 发起HTTP流式请求 with urlopen(http_url, timeout=300) as http_resp: # 直接将HTTP响应流传入FTP上传方法,无需本地缓存 ftp.storbinary(f"STOR {ftp_target_path}", http_resp, blocksize=chunk_size) ftp.quit() # 调用示例 if __name__ == "__main__": # 替换为实际参数即可使用 STREAM_HTTP_URL = "http://example.com/large_file.img" STREAM_FTP_HOST = "192.168.1.100" STREAM_FTP_USER = "admin" STREAM_FTP_PWD = "your_ftp_password" STREAM_FTP_SAVE_PATH = "/remote/data/saved_file.img" stream_http_to_ftp( http_url=STREAM_HTTP_URL, ftp_host=STREAM_FTP_HOST, ftp_user=STREAM_FTP_USER, ftp_passwd=STREAM_FTP_PWD, ftp_target_path=STREAM_FTP_SAVE_PATH, chunk_size=2*1024*1024 # 分片大小可根据网络情况调整,默认2MB )
Requests版本(适配需要自定义HTTP请求头、代理等复杂场景)
需要先安装依赖:pip install requests
import requests from ftplib import FTP def stream_http_to_ftp(http_url, ftp_host, ftp_user, ftp_passwd, ftp_target_path, chunk_size=2*1024*1024): ftp = FTP(ftp_host) ftp.login(user=ftp_user, passwd=ftp_passwd) ftp.set_pasv(True) # stream=True开启流式传输,不提前加载完整响应 with requests.get(http_url, stream=True, timeout=300, headers={"User-Agent": "your-custom-agent"}) as http_resp: # 自动处理gzip/deflate等压缩编码的文件 http_resp.raw.decode_content = True ftp.storbinary(f"STOR {ftp_target_path}", http_resp.raw, blocksize=chunk_size) ftp.quit()
注意事项
- 目前主流FTP服务端均支持流式上传,无需额外配置服务端
- 传输过程中如果出现网络中断,默认会终止传输,如有需要可结合HTTP的Range请求头和FTP的
rest()方法实现断点续传 - 可自定义流包装类统计已传输字节数,实现传输进度打印功能
- 多文件批量传输时只需在外层套循环遍历文件列表即可
内容的提问来源于stack exchange,提问作者Saleh
相关产品推荐
相关产品推荐

