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

9

我长期以来一直在处理 .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 解压缩文件一样)。
我该如何:
  1. 使用 Python 3 将 .xzlzma2) 文件的内容解压缩到一个文件夹中?
  2. 使用 Python 3 将 .zstZstandard)文件的内容解压缩到一个文件夹中?
重要提示:我正在解压缩非常大的文件,因此如果解决方案考虑到任何潜在的内存错误,那就太好了。

zstd 命令行界面可以解压缩 .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
@Cyan 很高兴知道这个。不过在 Python 3 中该怎么做呢? :) - Aventinus
通过将CLI作为外部命令行实用程序调用?如果您必须使用更紧密的集成,您可能会对Python包装器感兴趣。 - Cyan
1个回答

11

使用lzma模块可以解压LZMA数据,只需用该模块打开文件,然后使用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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接