【问题标题】:Unzip folder by chunks in python在python中按块解压缩文件夹
【发布时间】:2023-07-18 03:18:02
【问题描述】:

我有一个很大的 zip 文件,其中包含许多我想按块解压缩的文件以避免消耗太多内存。

我尝试使用 python 模块zipfile,但我没有找到按块加载存档并将其提取到磁盘上的方法。

在 python 中有没有简单的方法来做到这一点?

编辑

@steven-rumbalski 正确地指出 zipfile 正确地处理大文件,无需加载完整存档即可逐个解压缩文件。

我的问题是我的 zip 文件在 AWS S3 上,而我的 EC2 实例无法在 RAM 中加载这么大的文件,所以我按块下载它,我想按块解压缩它。

【问题讨论】:

    标签: python python-3.x unzip


    【解决方案1】:

    您不需要特殊的方法来将大型存档解压到磁盘。源Lib/zipfile.py 表明zipfile 已经是内存高效的。创建zipfile.ZipFile 对象不会将整个文件读入内存。相反,它只是读取 ZIP 文件的目录。 ZipFile.extractall() 使用从io.BufferedIOBase 的子类复制的shutil.copyfileobj() 提取文件一次

    如果您只想一次性提取 Python 提供的命令行快捷方式:

    python -m zipfile -e archive.zip target-dir/
    

    【讨论】:

    • 你是对的 zipfile 处理得很好。但我的上下文有点复杂。关键是我的 zip 文件在 S3 服务器上,我无法加载完整的 zip,因为实例无法在 RAM 中处理它,所以我按块下载 zip 文件,我想按块解压缩
    • 您不需要在 RAM 中保存整个文件。您仍然需要在磁盘上 有一个完整的文件,因为 zip 处理需要在文件内部进行查找。要将文件下载到磁盘,您也不需要将其全部读入内存;分块读取,分块写入临时文件,然后使用该文件,就足够了。
    • 谢谢@9000,你也是对的。我只是希望我可以避免将文件写入磁盘。
    【解决方案2】:

    您可以按如下方式使用 zipfile(或可能是 tarfile):

    import zipfile
    
    def extract_chunk(fn, directory, ix_begin, ix_end):
        with zipfile.ZipFile("{}/file.zip".format(directory), 'r') as zf:
            infos = zf.infolist()
            print(infos)
            for ix in range(max(0, ix_begin), min(ix_end, len(infos))):
                    zf.extract(infos[ix], directory)
            zf.close()
    
    directory = "path"
    extract_chunk("{}/file.zip".format(directory), directory, 0, 50)
    

    【讨论】:

    • 参数ix_beginix_end 似乎没有使用。 (此外,这似乎试图解决与 OP 状态不同的问题。)