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

如何在Django中流式传输整个文件夹且不读入全部内容到内存

Django 实现流式文件夹下载(无需全量加载内存)

针对现有方案的问题:

  • 需将所有文件加载进内存,大文件场景易引发内存溢出(OOM)
  • 迭代器示例无法配合open(file, 'rb').read(chunk_size)实现分块读取
  • 仅实现多文件分组,未保留原文件夹结构打包

以下是真正的流式文件夹下载实现,核心思路是通过分块读写生成ZIP压缩包,同时用Django的StreamingHttpResponse逐块返回内容,完全避免全量加载内存:

实现代码

import os
import zipfile
from io import BytesIO
from django.http import StreamingHttpResponse

def stream_zip(folder_path):
    zip_buffer = BytesIO()
    # 使用压缩格式,追求速度可替换为zipfile.ZIP_STORED
    with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
        # 遍历目标文件夹的所有层级
        for root, _, files in os.walk(folder_path):
            for file_name in files:
                file_full_path = os.path.join(root, file_name)
                # 保留原文件夹结构,作为压缩包内的文件路径
                arcname = os.path.relpath(file_full_path, folder_path)
                
                # 分块读取本地文件,写入压缩包
                with zip_file.open(arcname, 'w') as zip_entry:
                    with open(file_full_path, 'rb') as local_file:
                        # 8KB块大小,可根据需求调整
                        while chunk := local_file.read(8192):
                            zip_entry.write(chunk)
                
                # 输出当前已生成的压缩包内容块
                zip_buffer.seek(0)
                yield zip_buffer.read()
                # 重置缓冲区,准备下一个文件的写入
                zip_buffer.seek(0)
                zip_buffer.truncate()
    
    # 输出压缩包收尾内容
    zip_buffer.seek(0)
    yield zip_buffer.read()

def download_folder_view(request):
    # 替换为你的目标文件夹绝对路径
    target_folder = "/path/to/your/folder"
    response = StreamingHttpResponse(
        stream_zip(target_folder),
        content_type="application/zip"
    )
    response["Content-Disposition"] = 'attachment; filename="downloaded_folder.zip"'
    return response

方案优势

  • 低内存占用:每个文件分块读取、分块写入压缩包,再分块返回给客户端,内存仅需容纳单个文件块和少量压缩缓存
  • 真实文件夹打包:通过os.path.relpath保留原文件夹的层级结构,解压后与原文件夹一致
  • 兼容分块读取:直接使用open(file, 'rb').read(chunk_size)实现文件分块,完全匹配需求

注意事项

  • 确保Django运行进程拥有目标文件夹及所有文件的读取权限
  • 块大小(示例中为8KB)可根据服务器性能、文件平均大小调整,平衡内存占用和传输效率
  • 若无需压缩,将zipfile.ZIP_DEFLATED替换为zipfile.ZIP_STORED可大幅提升打包速度

内容的提问来源于stack exchange,提问作者Natthaphon Hongcharoen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:07:43