如何使用 Python 3 将 lzma2 (.xz) 和 zstd (.zst) 文件解压缩到文件夹中?

Posted

技术标签:

【中文标题】如何使用 Python 3 将 lzma2 (.xz) 和 zstd (.zst) 文件解压缩到文件夹中?【英文标题】:How to decompress lzma2 (.xz) and zstd (.zst) files into a folder using Python 3? 【发布时间】:2019-03-15 13:59:25 【问题描述】:

我已经使用.bz2 文件工作了很长时间。要将.bz2 文件解压缩/解压缩到特定文件夹中,我一直在使用以下函数:

destination_folder = 'unpacked/'
def decompress_bz2_to_folder(input_file):
    unpackedfile = bz2.BZ2File(input_file)
    data = unpackedfile.read()
    open(destination_folder, 'wb').write(data)

最近我获得了带有.xz(不是.tar.xz)和.zst 扩展名的文件列表。我糟糕的研究技能告诉我,前者是lzma2 压缩,后者是Zstandard

但是,我找不到将这些档案的内容解压缩到文件夹中的简单方法(就像我对 .bz2 文件所做的那样)。

我该怎么做:

    .xz (lzma2) 文件的内容解压到一个文件夹中 蟒蛇3? 使用 Python 3 将 .zst (Zstandard) 文件的内容解压到文件夹中?

重要提示:我正在解压very large files,所以如果解决方案考虑到任何潜在的内存错误,那就太好了.

【问题讨论】:

zstd cli 可以解压缩 .xz.zst 文件,如果使用适当的选项构建的话。这可以通过zstd -vV 进行检查。示例:zstd -vV*** zstd command line interface 64-bits v1.3.2, by Yann Collet ****** supports: zstd, zstd legacy v0.4+, gzip, lz4, lzma, xz @Cyan 很高兴知道。但是如何在 Python 3 中完成呢? :) 通过调用 CLI 作为外部命令行实用程序?如果您必须改用更紧密的集成,您可能对python wrapper 感兴趣。 【参考方案1】:

LZMA 数据可以使用lzma module 解压,只需使用该模块打开文件,然后使用shutil.copyfileobj() 将解压后的数据有效地复制到输出文件,而不会遇到内存问题:

import lzma
import pathlib
import shutil

def decompress_lzma_to_folder(input_file):
    input_file = pathlib.Path(input_file)
    with lzma.open(input_file) as compressed:
        output_path = pathlib.Path(destination_dir) / input_file.stem
        with open(output_path, 'wb') as destination:
            shutil.copyfileobj(compressed, destination)
        

Python 标准库尚不支持 Zstandard 压缩,您可以使用 zstandard(来自 Mozilla 和 Mercurial 项目的 IndyGreg)或 zstd;后者可能对您的需求来说太基础了,而zstandard 提供了一个特别适合读取文件的流式 API。

我在这里使用zstandard 库来受益于它实现的复制API,它可以让您同时解压缩和复制,类似于shutil.copyfileobj() 的工作方式:

import zstandard
import pathlib

def decompress_zstandard_to_folder(input_file):
    input_file = pathlib.Path(input_file)
    with open(input_file, 'rb') as compressed:
        decomp = zstandard.ZstdDecompressor()
        output_path = pathlib.Path(destination_dir) / input_file.stem
        with open(output_path, 'wb') as destination:
            decomp.copy_stream(compressed, destination)

【讨论】:

以上是关于如何使用 Python 3 将 lzma2 (.xz) 和 zstd (.zst) 文件解压缩到文件夹中?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 LZMA2 文件 (.xz / liblzma) 的未压缩大小

7zip的lzma和lzma2算法在啥情况下压缩率不一样

SharpCompress & LZMA2 7z 存档 - 特定文件的提取速度非常慢。为啥?备择方案?

为啥使用LZMA2算法压缩的文件,想从中提取某一文件时要解压(计算)完整个压缩包才能解出来?

好压压缩算法里LZMA算法和LZMA2有啥区别?

如何将参数从 Python 3.x 中的类定义传递给元类?