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

使用Python拆分超过1MB的Zip文件:现有代码拆分功能失效问题求助

解决Zip文件拆分失效的问题

你的拆分功能失效的核心原因是 SplitFileWriter 的设计目标是将数据拆分为多个磁盘文件(比如 output.001、output.002 这样的分片),而不是直接在内存中生成多个字节块。你把单个 BytesIO 对象传给它,它只会把所有压缩后的数据写入到这个单一的内存缓冲区里,自然不会产生拆分效果。另外,你用 zipfile.ZipFile 的 "a" 模式也不合适——因为你是从头创建Zip文件,应该用 "w" 模式,而且 ZipFile 会在上下文管理器退出时才将所有数据写入目标对象,这时候 SplitFileWriter 已经关闭,可能导致数据写入不完整。

下面给出两种针对性的解决方案:

方案1:内存中直接拆分Zip数据(推荐,无磁盘IO)

先完整生成Zip文件到内存缓冲区,再手动将其拆分为指定大小的字节块,全程在内存中完成:

from io import BytesIO
import zipfile
import xml.etree.ElementTree as etree

# 生成XML数据(你的原有逻辑)
tree = etree.ElementTree(batch_element)
xml_object = BytesIO()
tree.write(xml_object, pretty_print=True, xml_declaration=False, encoding="utf-8")
xml_file = xml_object.getvalue()

# 第一步:生成完整的Zip文件到内存
zip_buffer = BytesIO()
# 启用ZIP_DEFLATED压缩,可选但建议开启以减小体积
with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
    zip_file.writestr('Batch.xml', xml_file)
zip_buffer.seek(0)  # 将缓冲区指针移到开头
zip_data = zip_buffer.getvalue()

# 第二步:拆分Zip数据为1MB的字节块
CHUNK_SIZE = 1 * 1024 * 1024  # 1MB
split_chunks = []
remaining_data = zip_data

while len(remaining_data) > 0:
    chunk = remaining_data[:CHUNK_SIZE]
    split_chunks.append(chunk)
    remaining_data = remaining_data[CHUNK_SIZE:]

# 验证分片结果
for idx, chunk in enumerate(split_chunks):
    print(f"分片 {idx+1} 大小:{len(chunk)} 字节")

方案2:用SplitFileWriter生成磁盘分片再读取为字节

如果你一定要用SplitFileWriter生成标准的分片文件格式,可以先让它输出到磁盘,再读取这些文件的字节内容:

from split_file_reader.split_file_writer import SplitFileWriter
import zipfile
from io import BytesIO
import xml.etree.ElementTree as etree
import os

# 生成XML数据(你的原有逻辑)
tree = etree.ElementTree(batch_element)
xml_object = BytesIO()
tree.write(xml_object, pretty_print=True, xml_declaration=False, encoding="utf-8")
xml_file = xml_object.getvalue()

# 第一步:用SplitFileWriter生成磁盘分片
output_prefix = "batch_zip"
CHUNK_SIZE = 1 * 1024 * 1024

with SplitFileWriter(output_prefix, CHUNK_SIZE) as sfw:
    with zipfile.ZipFile(sfw, "w", zipfile.ZIP_DEFLATED) as zip_file:
        zip_file.writestr('Batch.xml', xml_file)

# 第二步:读取所有分片文件的字节内容
split_chunks = []
idx = 1
while True:
    chunk_filename = f"{output_prefix}.{idx:03d}"
    if not os.path.exists(chunk_filename):
        break
    with open(chunk_filename, "rb") as f:
        split_chunks.append(f.read())
    # 可选:读取后删除临时分片文件
    os.remove(chunk_filename)
    idx += 1

注意事项

  • 方案1更适合内存操作,避免磁盘IO,效率更高;
  • 方案2适合需要生成标准分片文件(供其他工具读取)的场景;
  • 创建ZipFile时指定ZIP_DEFLATED可以启用压缩,大幅减小Zip文件体积,建议开启。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:17:41