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

Python中URL大文件流式写入gzip文件的实现问题

流式下载并直接写入gzip文件的正确实现

嘿,我完全懂你想边下载边压缩、避免把大文件全塞进内存的需求!你的思路方向是对的,但问题出在直接把r.raw传给compressor.compress()——r.raw是一个流对象,不是可直接压缩的字节块,流式处理的核心是分块读取、分块压缩、即时写入,这样内存里永远只存一小块数据。

问题分析

你当前的代码尝试一次性压缩整个r.raw流,但zlib.compress()需要传入字节数据而非流对象。正确的姿势是逐块拉取下载内容,每拿到一块就压缩一块,立刻写入文件,彻底规避大内存占用。

方法一:用zlib手动控制流式压缩

下面是修正后的完整代码,我加了详细注释:

import requests
import zlib

url = "http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv"
save_file_path = "output.gz"

# 开启流式下载模式
with requests.get(url, stream=True) as r:
    r.raise_for_status()  # 先检查请求是否成功,避免无效流
    # 初始化gzip格式的压缩对象(wbits加16是为了生成标准gzip头/尾,否则是deflate格式)
    compressor = zlib.compressobj(wbits=zlib.MAX_WBITS | 16)
    with open(save_file_path, 'wb') as f:
        # 分块读取内容,每次1MB(可根据内存情况调整块大小)
        for chunk in r.iter_content(chunk_size=1024*1024):
            if chunk:  # 跳过可能的空块
                # 压缩当前字节块
                compressed_chunk = compressor.compress(chunk)
                # 立即写入压缩后的内容
                f.write(compressed_chunk)
        # 最后刷新压缩器,把剩余未写入的压缩数据全部导出
        f.write(compressor.flush())

方法二:用gzip模块更简洁实现

如果你不需要底层压缩的精细控制,Python自带的gzip模块已经封装了流式压缩逻辑,代码会更清爽:

import requests
import gzip

url = "http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv"
save_file_path = "output.gz"

with requests.get(url, stream=True) as r:
    r.raise_for_status()
    # 用gzip.GzipFile直接以写模式打开,自动处理压缩逻辑
    with gzip.GzipFile(save_file_path, 'wb') as f:
        # 逐块写入原始数据,gzip会自动完成压缩
        for chunk in r.iter_content(chunk_size=1024*1024):
            if chunk:
                f.write(chunk)

这种方式不需要手动管理压缩对象,gzip模块会帮你处理所有压缩细节,代码可读性更高。

关键注意点

  • 必须用iter_content(chunk_size=...)分块读取,而非直接操作r.raw(当然也可以用r.raw.read(chunk_size),但iter_content会自动处理空块场景)。
  • 别忘了加r.raise_for_status(),避免下载失败时还继续写入无效内容。
  • 用zlib时一定要设置wbits=zlib.MAX_WBITS | 16,否则生成的是deflate格式文件,大部分解压工具无法识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:44:11