Модуль tarfile
позволяет читать и записывать tar
архивы, в том числе использующие gzip
, bz2
и lzma
сжатие. Используйте модуль zipfile
для чтения или записи .zip
архивов или функции более высокого уровня модуля shutil
.
Изменено в Python 3.12: Архивы извлекаются с помощью фильтра, который позволяет либо ограничить неожиданные/опасные функции, либо подтвердить, что они ожидаемы и архиву полностью доверяют. По умолчанию архивам полностью доверяют, но это значение по умолчанию устарело и планируется изменить в Python 3.14.
gzip
, bz2
и lzma
архивы, если доступны соответствующие модули.ustar
).pax
).tar
.Существует три формата tar
, которые можно создать с помощью модуля tarfile
:
USTAR_FORMAT
). Он поддерживает имена файлов длиной до 256 символов и имена ссылок до 100 символов. Максимальный размер файла составляет 8 ГиБ. Это старый и ограниченный, но широко поддерживаемый формат.GNU_FORMAT
). Он поддерживает длинные имена файлов и ссылок, файлы размером более 8 ГБ и разреженные файлы. Это де-факто стандарт для систем GNU/Linux. Модуль tarfile
полностью поддерживает расширения tar для GNU для длинных имен, поддержка разреженных файлов доступна только для чтения.Формат POSIX.1-2001 (PAX_FORMAT
). Это самый гибкий формат практически без ограничений. Он поддерживает длинные имена файлов и ссылок, большие файлы и хранит пути в портативном виде. Современные реализации tar
, включая GNU tar, bsdtar/libarchive и star, полностью поддерживают расширенные функции pax
. Некоторые старые или неподдерживаемые библиотеки могут этого не делать, но должны обрабатывать архивы pax
так, как если бы они были в универсально поддерживаемом формате ustar
. Это текущий формат по умолчанию для новых архивов.
Формат pax
расширяет существующий формат ustar
дополнительными заголовками для информации, которая не может быть сохранена иначе. Существует два вида заголовков pax
: расширенные заголовки влияют только на последующий заголовок файла, глобальные заголовки действительны для всего архива и влияют на все последующие файлы. Все данные в заголовке pax
кодируются в UTF-8 по причинам переносимости.
Есть еще несколько вариантов формата tar
, которые можно только читать и извлекать информацию:
tar
из Unix Seventh Edition, в котором хранятся только обычные файлы и каталоги. Имена не должны быть длиннее 100 символов, информация об имени пользователя/группы отсутствует. Некоторые архивы имеют неверные контрольные суммы заголовков в случае полей с не-ASCII символами.Формат tar
изначально задумывался для создания резервных копий на ленточных накопителях с основным упором на сохранение информации о файловой системе. В настоящее время архивы tar
обычно используются для распространения файлов и обмена архивами по сети. Одна из проблем исходного формата, который лежит в основе всех других форматов заключается в том, что не существует концепции поддержки различных кодировок символов. Например, обычный архив tar
, созданный в системе UTF-8, не может быть правильно прочитан в системе Latin-1, если он содержит символы не ASCII. Текстовые метаданные, такие как имена файлов, имена ссылок, имена пользователей/групп будут выглядеть поврежденными. К сожалению, нет способа автоматически определить кодировку архива. Формат pax
был разработан для решения этой проблемы. Он хранит метаданные не ASCII, используя универсальную кодировку символов UTF-8.
По умолчанию в модуля tarfile
установлен PAX_FORMAT
, для которого кодирование обычно не требуется, поскольку все метаданные хранятся с использованием UTF-8. Кодирование используется только в тех редких случаях, когда декодируются двоичные заголовки pax
или когда хранятся строки с суррогатными символами.
tarfile
:Извлечение всего tar
архива в текущий рабочий каталог:
import tarfile tar = tarfile.open("sample.tar.gz") tar.extractall(filter='data') tar.close() # Эквивалентно with tarfile.open("sample.tar.gz") as tar: tar.extractall(filter='data')
Извлечение подмножества файлов и каталогов из архива tar
архива с помощью TarFile.extractall()
, используя функцию генератора вместо списка:
import os, tarfile def py_files(members): for tarinfo in members: if os.path.splitext(tarinfo.name)[1] == ".py": yield tarinfo with tarfile.open("sample.tar.gz") as tar: tar.extractall(members=py_files(tar))
Как создать несжатый архив tar
из списка имен файлов:
import tarfile with tarfile.open("sample.tar", "w") as tar: for name in ["foo", "bar", "quux"]: tar.add(name)
Как прочитать сжатый архивом tar.gz
и показать некоторую информацию об элементах архива:
import tarfile with tarfile.open("sample.tar.gz", "r:gz") as tar: for tarinfo in tar: print(tarinfo.name, "is", tarinfo.size, "bytes in size and is", end="") if tarinfo.isreg(): print("a regular file.") elif tarinfo.isdir(): print("a directory.") else: print("something else.")
Как создать архив и сбросить информацию о пользователе, используя параметр фильтра в TarFile.add()
:
import tarfile def reset(tarinfo): tarinfo.uid = tarinfo.gid = 0 tarinfo.uname = tarinfo.gname = "root" return tarinfo with tarfile.open("sample.tar.gz", "w:gz") as tar: tar.add("foo", filter=reset)