You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask应用如何生成不含服务器目录结构的流式Zip文件

Flask生成不含服务器目录结构的Zip文件解决方案

核心问题是你往Zip包中添加文件时,默认使用了服务器上的完整文件路径作为压缩包内的路径。解决关键是指定压缩包内的文件名(即arcname参数),只保留文件本身的名称而非完整路径。

以下是两种可行的实现方案:

方案一:直接指定arcname为文件名

使用zipfile.ZipFile.write()方法时,通过arcname参数明确设置压缩包内的文件名称,只保留原始文件名即可。

from flask import Flask, send_file
import zipfile
import os
from io import BytesIO

app = Flask(__name__)

@app.route('/download-images')
def download_images():
    # 替换为你的图片目录路径
    target_dir = '/dir/to/the/files'
    # 在内存中创建Zip文件,避免写入服务器磁盘
    zip_buffer = BytesIO()
    
    with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zipf:
        # 遍历目标目录下的所有文件
        for root, _, files in os.walk(target_dir):
            for file in files:
                # 筛选图片文件,可根据需求调整后缀
                if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
                    full_file_path = os.path.join(root, file)
                    # 关键:用arcname指定压缩包内仅保留文件名
                    zipf.write(full_file_path, arcname=file)
    
    # 将缓冲区指针移到文件开头,确保send_file能正确读取
    zip_buffer.seek(0)
    # 返回Zip文件给用户
    return send_file(
        zip_buffer,
        mimetype='application/zip',
        as_attachment=True,
        download_name='images.zip'
    )

if __name__ == '__main__':
    app.run(debug=True)

方案二:切换工作目录后添加文件

先切换到目标图片目录,再添加文件,此时使用相对路径即可避免带上服务器的完整路径,适合批量处理目录下所有文件的场景。

from flask import Flask, send_file
import zipfile
import os
from io import BytesIO

app = Flask(__name__)

@app.route('/download-images')
def download_images():
    target_dir = '/dir/to/the/files'
    zip_buffer = BytesIO()
    
    # 保存当前工作目录,后续恢复避免影响其他逻辑
    original_work_dir = os.getcwd()
    try:
        # 切换到目标图片目录
        os.chdir(target_dir)
        with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zipf:
            # 遍历当前目录(.)下的所有文件
            for root, _, files in os.walk('.'):
                for file in files:
                    if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
                        relative_path = os.path.join(root, file)
                        # 仅保留文件名,若需要保留子目录结构可去掉os.path.basename
                        zipf.write(relative_path, arcname=os.path.basename(relative_path))
    finally:
        # 恢复原工作目录
        os.chdir(original_work_dir)
    
    zip_buffer.seek(0)
    return send_file(
        zip_buffer,
        mimetype='application/zip',
        as_attachment=True,
        download_name='images.zip'
    )

if __name__ == '__main__':
    app.run(debug=True)

注意事项

  • 如果目标目录下存在同名文件(比如不同子目录下有相同文件名的图片),直接使用文件名会导致压缩包内文件被覆盖。这种情况可以给文件名添加前缀(比如子目录名),或者在遍历过程中检查并跳过重复文件。
  • 使用BytesIO在内存中生成Zip文件,避免在服务器磁盘上创建临时文件,节省磁盘资源且更高效。

内容的提问来源于stack exchange,提问作者James Watson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 08:20:53