Как распаковать файлы lzma2 (.xz) и zstd (.zst) в папку с помощью Python 3? - PullRequest
3 голосов
/ 15 марта 2019

Я давно работаю с .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. Распакуйте содержимое файла .xz (lzma2) в папку, используя Python 3?
  2. Распаковать содержимое файла .zst (Zstandard) в папку с помощью Python 3?

Важное примечание: Я распаковываю очень большие файлы , поэтому было бы замечательно, если бы решение учитывало любой потенциальный Ошибки памяти .

1 Ответ

4 голосов
/ 20 марта 2019

Данные 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 (от IndyGreg из Mozilla)и проект Mercurial) или zstd;последнее, возможно, слишком базовое для ваших нужд, в то время как zstandard предлагает потоковый API, специально предназначенный для чтения файлов.

Я использую здесь библиотеку zstandard, чтобы воспользоваться преимуществами реализуемого им API копирования, которыйпозволяет распаковывать и копировать одновременно, как работает shutil.copyfileobj():

import zstandard
import pathlib
import shutil

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)
...