Как создать полностью сжатый tar-файл с помощью Python?


Ответы:


186

Чтобы построить .tar.gz(иначе .tgz) для всего дерева каталогов:

import tarfile
import os.path

def make_tarfile(output_filename, source_dir):
    with tarfile.open(output_filename, "w:gz") as tar:
        tar.add(source_dir, arcname=os.path.basename(source_dir))

Это создаст сжатый tar-архив, содержащий одну папку верхнего уровня с тем же именем и содержимым, что и source_dir.


31
В качестве примечания для читателей, если вы не arcname=os.path.basename(source_dir)укажете, он предоставит вам всю структуру путей source_dirв tar-файле (в большинстве случаев это, вероятно, неудобно).
Brōtsyorfuzthrāx

12
Вторая заметка; использование arcname=os.path.basename(source_dir)still означает, что в архиве есть папка с содержимым source_dir. Если вы хотите, чтобы корень архива содержал само содержимое, а не содержимое папки, используйте arcname=os.path.sepвместо этого.
Jonathan H

2
@Sheljohn, к сожалению, это не совсем правильно, потому что если использовать os.path.sep, то в архиве будет сервис "." или папка «/», что обычно не является проблемой, но иногда это может быть проблемой, если вы позже обработаете этот архив программно. Кажется, единственный настоящий чистый способ - os.walk
Крестный отец

Чтобы избавиться от всей структуры каталогов, просто используйте arcname='.'. Не нужно использовать os.walk.
edouardtheron

85
import tarfile
tar = tarfile.open("sample.tar.gz", "w:gz")
for name in ["file1", "file2", "file3"]:
    tar.add(name)
tar.close()

Если вы хотите создать сжатый файл tar.bz2, просто замените имя расширения файла на «.tar.bz2» и «w: gz» на «w: bz2».


10
Вам действительно следует использовать with tarfile.open( ..Python, а не вызывать openи closeвручную. То же самое и при открытии обычных файлов.
Jonathan H

31

Вы вызываете tarfile.open с помощьюmode='w:gz' , что означает «Открыть для записи в сжатом gzip».

Вы, вероятно, захотите закончить имя файла ( nameаргумент open) на .tar.gz, но это не влияет на возможности сжатия.

Кстати, вы обычно получаете лучшее сжатие с режимом 'w:bz2', так же как tarобычно может сжиматься даже лучше, bzip2чем с gzip.


6
Замечу, что имя файла tar-архивов, сжатых с помощью bzip2, должно заканчиваться на ".tar.bz2".
Игнасио Васкес-Абрамс,

8

В предыдущих ответах рекомендуется использовать tarfileмодуль Python для создания .tar.gzфайла в Python. Очевидно, что это хорошее решение в стиле Python, но у него есть серьезный недостаток в скорости архивирования. В этом вопросе упоминается, что tarfileэто примерно в два раза медленнее, чемtar утилита в Linux. По моему опыту, эта оценка вполне верна.

Итак, для более быстрого архивирования вы можете использовать tarкоманду using subprocessmodule:

subprocess.call(['tar', '-czf', output_filename, file_to_archive])

0

В этом tar.gz файл сжимается в каталоге открытого просмотра. В решении используется os.path.basename (file_directory)

with tarfile.open("save.tar.gz","w:gz"):
      for file in ["a.txt","b.log","c.png"]:
           tar.add(os.path.basename(file))

его использование в файле tar.gz сжать в каталоге


0

В дополнение к ответу @Aleksandr Tukallo вы также можете получить вывод и сообщение об ошибке (если происходит). Сжатие папки с использованием tarдовольно хорошо объясняется в следующем ответе .

import traceback
import subprocess

try:
    cmd = ['tar', 'czfj', output_filename, file_to_archive]
    output = subprocess.check_output(cmd).decode("utf-8").strip() 
    print(output)          
except Exception:       
    print(f"E: {traceback.format_exc()}")       
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.