背景 链接到标题 在 web 场景下,经常会碰到下载文件的需求,通常小文件我们会采用 Flask send_file 或者 send_from_directory的方式,下载,但是当下载的文件是一个大压缩文件(>1GiB)时,这种方式就显得不友好了,我们需要采用流式下载的方式返回给客户端。
流式下载 链接到标题 简单实现:
from flask import Response @app.route("/download/<file_path>", methods=["GET"]) def download(file_path): def generate(): if not os.path.exists(file_path): raise "File not found." with open(file_path, "rb") as f: while True: chunk = f.read(chunk_size=10 * 1024 * 1024) if not chunk: break yield chunk return Response(generate(), content_type="application/octet-stream") 运行 Flask app,可以正确下载文件,但是下载只有实时速度,没有文件总大小,导致无法知道下载进度,也没有文件类型,这些我们都可以通过增加 header 字段实现:
response = Response(generate(), mimetype='application/gzip') response.headers['Content-Disposition'] = 'attachment; filename={}.tar.gz'.format("download_file") response.headers['content-length'] = os.stat(str(file_path)).st_size return response 这样,我们下载文件就可以看到文件类型、文件总大小及已下载大小了,其中 mimetype 根据实际压缩文件类型修改匹配即可。