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

如何使用Python tarfile库提取tar.gz.part*格式的分卷压缩文件

解决方案

实现原理

你使用split切割的是完整tar.gz压缩输出流,每个分卷仅为完整流的一部分,并非独立的gzip文件,所以单独读取单个分卷时要么因为流不完整报EOFError,要么读取后续分卷时因为没有gzip文件头报格式错误。必须按partaa→partab→partac的顺序将所有分卷拼接为连续的完整字节流后,才能正常解压。

普通实现(适合分卷总大小不超过内存的场景)

import tarfile
import glob
from io import BytesIO

def extract_all_parts(part_prefix: str, extract_path: str):
    # 按名称排序自动得到aa/ab/ac的正确读取顺序
    part_files = sorted(glob.glob(f"{part_prefix}*"))
    if not part_files:
        raise FileNotFoundError("未找到匹配的分卷文件")
    
    # 拼接所有分卷为完整字节流
    full_stream = BytesIO()
    for part in part_files:
        with open(part, "rb") as f:
            full_stream.write(f.read())
    full_stream.seek(0)
    
    # 用流模式打开压缩包解压
    with tarfile.open(fileobj=full_stream, mode="r|gz") as tar:
        tar.extractall(path=extract_path)

# 调用示例,公共前缀传入分卷文件名的公共部分即可
extract_all_parts(part_prefix="20210914.tar.gz.part", extract_path="tmp")

低内存占用实现(适合分卷总大小超过内存的场景)

不需要一次性加载所有分卷到内存,逐块读取拼接:

import tarfile
import glob

def generate_chunks(part_files):
    for part in part_files:
        with open(part, "rb") as f:
            # 每次读取1MB块,可根据需要调整大小
            while chunk := f.read(1024 * 1024):
                yield chunk

def extract_all_parts_low_memory(part_prefix: str, extract_path: str):
    part_files = sorted(glob.glob(f"{part_prefix}*"))
    if not part_files:
        raise FileNotFoundError("未找到匹配的分卷文件")
    
    # 实现适配tarfile读取要求的拼接流类
    class ConcatenatedStream:
        def __init__(self, chunks):
            self.chunks = chunks
            self.buffer = b""
        
        def read(self, size=-1):
            while size == -1 or len(self.buffer) < size:
                try:
                    self.buffer += next(self.chunks)
                except StopIteration:
                    break
            if size == -1:
                res = self.buffer
                self.buffer = b""
            else:
                res = self.buffer[:size]
                self.buffer = self.buffer[size:]
            return res
    
    stream = ConcatenatedStream(generate_chunks(part_files))
    with tarfile.open(fileobj=stream, mode="r|gz") as tar:
        tar.extractall(path=extract_path)

# 调用示例
extract_all_parts_low_memory(part_prefix="20210914.tar.gz.part", extract_path="tmp")

内容的提问来源于stack exchange,提问作者Mr. Hobo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 02:21:00