tarfile — Чтение и запись архивных файлов tar

Источник: Lib/tarfile.py


Модуль tarfile позволяет читать и записывать tar-архивы, включая те, которые используют сжатие gzip, bz2 и lzma. Используйте модуль zipfile для чтения и записи файлов .zip или функции более высокого уровня в shutil.

Некоторые факты и цифры:

  • читает и записывает сжатые архивы gzip, bz2 и lzma, если соответствующие модули доступны.

  • поддержка чтения/записи для формата POSIX.1-1988 (ustar).

  • Поддержка формата GNU tar для чтения/записи, включая расширения longname и longlink, поддержка всех вариантов расширения sparse, включая восстановление разреженных файлов, только для чтения.

  • поддержка чтения/записи для формата POSIX.1-2001 (pax).

  • Работает с каталогами, обычными файлами, жесткими ссылками, символическими ссылками, fifos, символьными и блочными устройствами и может получать и восстанавливать информацию о файлах, такую как временная метка, разрешения на доступ и владелец.

Изменено в версии 3.3: Добавлена поддержка сжатия lzma.

Изменено в версии 3.12: Архивы извлекаются с помощью filter, что позволяет либо ограничить неожиданные/опасные функции, либо подтвердить, что они ожидаемы и архив полностью доверен. По умолчанию архивы являются полностью доверенными, но это значение устарело и будет изменено в Python 3.14.

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)

Возвращает объект TarFile для имени пути name. Подробную информацию об объектах TarFile и допустимых аргументах в виде ключевых слов см. в разделе Объекты TarFile.

mode должен быть строкой вида 'filemode[:compression]', по умолчанию он принимает значение 'r'. Здесь приведен полный список комбинаций режимов:

режим

действие

'r' or 'r:*'

Открыть для чтения с прозрачным сжатием (рекомендуется).

'r:'

Открыт для чтения исключительно без сжатия.

'r:gz'

Открыт для чтения со сжатием gzip.

'r:bz2'

Открыт для чтения со сжатием bzip2.

'r:xz'

Открыть для чтения со сжатием lzma.

'x' или 'x:'

Создайте tar-файл исключительно без сжатия. Вызывает исключение FileExistsError, если он уже существует.

'x:gz'

Создайте tar-файл с gzip-сжатием. Вызовите исключение FileExistsError, если он уже существует.

'x:bz2'

Создайте tar-файл со сжатием bzip2. Вызовите исключение FileExistsError, если он уже существует.

'x:xz'

Создайте tar-файл со сжатием lzma. Вызовите исключение FileExistsError, если он уже существует.

'a' or 'a:'

Открыть для добавления без сжатия. Файл создается, если он не существует.

'w' or 'w:'

Открыт для записи без сжатия.

'w:gz'

Открыт для записи с gzip-сжатием.

'w:bz2'

Открыт для записи со сжатием bzip2.

'w:xz'

Открыт для записи в сжатом виде lzma.

Обратите внимание, что 'a:gz', 'a:bz2' или 'a:xz' невозможны. Если режим не подходит для открытия определенного (сжатого) файла для чтения, то будет выдан сигнал ReadError. Чтобы избежать этого, используйте режим 'r'. Если метод сжатия не поддерживается, выдается сообщение CompressionError.

Если указан fileobj, он используется как альтернатива file object, открытому в двоичном режиме для name. Предполагается, что он находится в позиции 0.

Для режимов 'w:gz', 'x:gz', 'w|gz', 'w:bz2', 'x:bz2', 'w|bz2', tarfile.open() принимается ключевой аргумент compresslevel (по умолчанию 9) для указания уровня сжатия файла.

Для режимов 'w:xz' и 'x:xz', tarfile.open() принимает аргумент ключевого слова preset для указания уровня сжатия файла.

Для специальных целей существует второй формат для mode: 'filemode|[compression]'. tarfile.open() вернет объект TarFile, который обрабатывает свои данные как поток блоков. Никакого случайного поиска в файле производиться не будет. Если задано, fileobj может быть любым объектом, имеющим метод read() или write() (в зависимости от режима), который работает с байтами. bufsize задает размер блока и по умолчанию равен 20 * 512 байт. Используйте этот вариант в сочетании, например, с sys.stdin.buffer, сокетом file object или ленточным устройством. Однако такой объект TarFile ограничен тем, что не допускает произвольного доступа, см. Примеры. В настоящее время возможны следующие режимы:

Режим

Действие

'r|*'

Открыть поток блоков tar для чтения с прозрачным сжатием.

'r|'

Открыть поток несжатых tar-блоков для чтения.

'r|gz'

Открыть для чтения поток, сжатый gzip.

'r|bz2'

Открыть для чтения поток, сжатый в формате bzip2.

'r|xz'

Открыть для чтения поток, сжатый по методу lzma.

'w|'

Открыть несжатый поток для записи.

'w|gz'

Открыть сжатый gzip поток для записи.

'w|bz2'

Открыть сжатый в bzip2 поток для записи.

'w|xz'

Открыть сжатый поток в формате lzma для записи.

Изменено в версии 3.5: Добавлен режим 'x' (эксклюзивное создание).

Изменено в версии 3.6: Параметр name принимает значение path-like object.

Изменено в версии 3.12: Ключевой аргумент compresslevel также работает для потоков.

class tarfile.TarFile

Класс для чтения и записи tar-архивов. Не используйте этот класс напрямую: вместо него используйте tarfile.open(). См. Объекты TarFile.

tarfile.is_tarfile(name)

Возвращает True, если name является файлом архива tar, который модуль tarfile может прочитать. name может быть str, файлом или файлоподобным объектом.

Изменено в версии 3.9: Поддержка файлов и файлоподобных объектов.

Модуль tarfile определяет следующие исключения:

exception tarfile.TarError

Базовый класс для всех исключений tarfile.

exception tarfile.ReadError

Возникает при открытии tar-архива, который либо не может быть обработан модулем tarfile, либо каким-то образом является недействительным.

exception tarfile.CompressionError

Возникает, когда метод сжатия не поддерживается или когда данные не могут быть декодированы должным образом.

exception tarfile.StreamError

Повышается для ограничений, характерных для потокоподобных TarFile объектов.

exception tarfile.ExtractError

Возникает для нефатальных ошибок при использовании TarFile.extract(), но только если TarFile.errorlevel== 2.

exception tarfile.HeaderError

Вызывается TarInfo.frombuf(), если полученный буфер недействителен.

exception tarfile.FilterError

Базовый класс для членов refused по фильтрам.

tarinfo

Информация о члене, который фильтр не смог извлечь, в виде TarInfo.

exception tarfile.AbsolutePathError

Возникает при отказе извлечь член с абсолютным путем.

exception tarfile.OutsideDestinationError

Повышается при отказе извлечь член за пределами целевого каталога.

exception tarfile.SpecialFileError

Возникает при отказе от извлечения специального файла (например, устройства или трубы).

exception tarfile.AbsoluteLinkError

Возникает при отказе извлечь символическую ссылку с абсолютным путем.

exception tarfile.LinkOutsideDestinationError

Повышается при отказе от извлечения символической ссылки, указывающей за пределы целевого каталога.

Следующие константы доступны на уровне модуля:

tarfile.ENCODING

Кодировка символов по умолчанию: 'utf-8' в Windows, значение, возвращаемое sys.getfilesystemencoding() в противном случае.

tarfile.REGTYPE
tarfile.AREGTYPE

Обычный файл type.

tarfile.LNKTYPE

Ссылка (внутри tarfile) type.

tarfile.SYMTYPE

Символическая ссылка type.

tarfile.CHRTYPE

Специальное устройство для символов type.

tarfile.BLKTYPE

Специальное устройство блока type.

tarfile.DIRTYPE

Каталог type.

tarfile.FIFOTYPE

Специальное устройство FIFO type.

tarfile.CONTTYPE

Непрерывный файл type.

tarfile.GNUTYPE_LONGNAME

Длинное имя GNU tar type.

GNU tar longlink type.

tarfile.GNUTYPE_SPARSE

Разрозненный файл GNU tar type.

Каждая из следующих констант определяет формат tar-архива, который может создать модуль tarfile. Подробности см. в разделе Поддерживаемые форматы tar.

tarfile.USTAR_FORMAT

Формат POSIX.1-1988 (ustar).

tarfile.GNU_FORMAT

Формат GNU tar.

tarfile.PAX_FORMAT

Формат POSIX.1-2001 (pax).

tarfile.DEFAULT_FORMAT

Формат по умолчанию для создания архивов. В настоящее время это PAX_FORMAT.

Изменено в версии 3.8: Формат по умолчанию для новых архивов был изменен на PAX_FORMAT с GNU_FORMAT.

См.также

Модуль zipfile

Документация стандартного модуля zipfile.

Операции архивирования

Документация по средствам архивации более высокого уровня, предоставляемым стандартным модулем shutil.

GNU tar manual, Basic Tar Format

Документация по архивным файлам tar, включая расширения GNU tar.

Объекты TarFile

Объект TarFile предоставляет интерфейс для работы с tar-архивом. Архив tar представляет собой последовательность блоков. Член архива (сохраненный файл) состоит из блока заголовка, за которым следуют блоки данных. Файл можно хранить в tar-архиве несколько раз. Каждый член архива представлен объектом TarInfo, подробнее см. в разделе Объекты TarInfo.

Объект TarFile может быть использован в качестве менеджера контекста в операторе with. Он будет автоматически закрыт после завершения блока. Обратите внимание, что в случае исключения архив, открытый для записи, не будет завершен; будет закрыт только внутренний используемый файловый объект. Пример использования см. в разделе Примеры.

Added in version 3.2: Добавлена поддержка протокола управления контекстом.

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=1, stream=False)

Все следующие аргументы являются необязательными и могут быть доступны как атрибуты экземпляра.

name - это имя пути к архиву. name может быть path-like object. Его можно опустить, если указан fileobj. В этом случае используется атрибут name файлового объекта, если он существует.

mode - это либо 'r' для чтения из существующего архива, 'a' для добавления данных в существующий файл, 'w' для создания нового файла, перезаписывающего существующий, либо 'x' для создания нового файла, только если он еще не существует.

Если задан fileobj, то он используется для чтения или записи данных. Если это можно определить, то mode переопределяется режимом fileobj. fileobj будет использоваться с позиции 0.

Примечание

fileobj не закрыт, когда TarFile закрыт.

format управляет форматом архива для записи. Он должен быть одной из констант USTAR_FORMAT, GNU_FORMAT или PAX_FORMAT, которые определяются на уровне модуля. При чтении формат будет определяться автоматически, даже если в одном архиве присутствуют разные форматы.

Аргумент tarinfo можно использовать для замены класса TarInfo, используемого по умолчанию, на другой.

Если dereference имеет значение False, в архив добавляются символические и жесткие ссылки. Если значение True, добавьте в архив содержимое целевых файлов. Это не влияет на системы, не поддерживающие символические ссылки.

Если ignore_zeros имеет значение False, считайте пустой блок концом архива. Если оно равно True, пропускайте пустые (и недействительные) блоки и старайтесь получить как можно больше членов. Это полезно только для чтения конкатенированных или поврежденных архивов.

Для параметра debug можно установить значение от 0 (нет отладочных сообщений) до 3 (все отладочные сообщения). Сообщения записываются в sys.stderr.

errorlevel управляет тем, как обрабатываются ошибки извлечения, см. the corresponding attribute.

Аргументы encoding и errors определяют кодировку символов, которая будет использоваться для чтения или записи архива, и способ обработки ошибок преобразования. Настройки по умолчанию подойдут большинству пользователей. Более подробная информация приведена в разделе Проблемы с юникодом.

Аргумент pax_headers - это необязательный словарь строк, которые будут добавлены в качестве глобального заголовка pax, если format имеет значение PAX_FORMAT.

Если stream имеет значение True, то при чтении архива информация о файлах в архиве не кэшируется, что экономит память.

Изменено в версии 3.2: Используйте 'surrogateescape' в качестве значения по умолчанию для аргумента errors.

Изменено в версии 3.5: Добавлен режим 'x' (эксклюзивное создание).

Изменено в версии 3.6: Параметр name принимает значение path-like object.

Изменено в версии 3.13: Добавьте параметр stream.

classmethod TarFile.open(...)

Альтернативный конструктор. Функция tarfile.open() фактически является ярлыком для этого метода класса.

TarFile.getmember(name)

Возвращает объект TarInfo для члена name. Если имя не найдено в архиве, возвращается KeyError.

Примечание

Если член встречается в архиве более одного раза, его последняя встреча считается наиболее актуальной версией.

TarFile.getmembers()

Возвращает члены архива в виде списка объектов TarInfo. Список имеет тот же порядок, что и члены в архиве.

TarFile.getnames()

Возвращает члены в виде списка их имен. Он имеет тот же порядок, что и список, возвращаемый командой getmembers().

TarFile.list(verbose=True, *, members=None)

Выведите оглавление в sys.stdout. Если значение verbose равно False, выводятся только имена членов. Если значение verbose равно True, будет выведен вывод, аналогичный ls -l. Если задано необязательное значение members, оно должно быть подмножеством списка, возвращаемого getmembers().

Изменено в версии 3.5: Добавлен параметр members.

TarFile.next()

Возвращает следующий член архива в виде объекта TarInfo, когда TarFile открыт для чтения. Верните None, если больше ничего не доступно.

TarFile.extractall(path='.', members=None, *, numeric_owner=False, filter=None)

Извлечь все члены из архива в текущий рабочий каталог или каталог path. Если указано необязательное значение members, оно должно быть подмножеством списка, возвращаемого getmembers(). Информация о каталоге, такая как владелец, время модификации и права доступа, устанавливается после извлечения всех членов. Это делается для решения двух проблем: Время модификации каталога сбрасывается каждый раз, когда в нем создается файл. И если права доступа к каталогу не разрешают запись, извлечение файлов в него будет неудачным.

Если numeric_owner равно True, то для задания владельца/группы извлеченных файлов используются номера uid и gid из tarfile. В противном случае используются именованные значения из tar-файла.

Аргумент фильтр определяет, как members будут изменены или отклонены перед извлечением. Подробности см. в разделе Фильтры для извлечения. Рекомендуется задавать этот параметр явно в зависимости от того, какие функции tar вам необходимо поддерживать.

Предупреждение

Никогда не извлекайте архивы из ненадежных источников без предварительной проверки. Возможно, что файлы создаются вне path, например, члены с абсолютными именами, начинающимися с "/", или имена с двумя точками "..".

Установите значение filter='data', чтобы предотвратить наиболее опасные проблемы безопасности, и прочитайте раздел Фильтры для извлечения для получения подробной информации.

Изменено в версии 3.5: Добавлен параметр numeric_owner.

Изменено в версии 3.6: Параметр path принимает значение path-like object.

Изменено в версии 3.12: Добавлен параметр фильтр.

TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False, filter=None)

Извлеките член архива в текущий рабочий каталог, используя его полное имя. Информация о файле извлекается как можно точнее. member может быть именем файла или объектом TarInfo. Вы можете указать другой каталог с помощью path. path может быть объектом path-like object. Атрибуты файла (владелец, mtime, mode) устанавливаются, если только set_attrs не равно false.

Аргументы numeric_owner и filter такие же, как и для extractall().

Примечание

Метод extract() не позволяет решить несколько проблем с извлечением. В большинстве случаев следует использовать метод extractall().

Предупреждение

См. предупреждение для extractall().

Установите значение filter='data', чтобы предотвратить наиболее опасные проблемы безопасности, и прочитайте раздел Фильтры для извлечения для получения подробной информации.

Изменено в версии 3.2: Добавлен параметр set_attrs.

Изменено в версии 3.5: Добавлен параметр numeric_owner.

Изменено в версии 3.6: Параметр path принимает значение path-like object.

Изменено в версии 3.12: Добавлен параметр фильтр.

TarFile.extractfile(member)

Извлечение члена из архива в виде файлового объекта. member может быть именем файла или объектом TarInfo. Если член является обычным файлом или ссылкой, возвращается объект io.BufferedReader. Для всех остальных существующих членов возвращается None. Если член не встречается в архиве, возвращается KeyError.

Изменено в версии 3.3: Возвращает объект io.BufferedReader.

Изменено в версии 3.13: Возвращаемый объект io.BufferedReader имеет атрибут mode, который всегда равен 'rb'.

TarFile.errorlevel: int

Если errorlevel равен 0, ошибки игнорируются при использовании TarFile.extract() и TarFile.extractall(). Тем не менее, они появляются в виде сообщений об ошибках в отладочном выводе, если debug больше 0. Если 1 (по умолчанию), все фатальные ошибки выдаются как исключения OSError или FilterError. Если 2, то все нефатальные ошибки также выдаются как исключения TarError.

Некоторые исключения, например, вызванные неправильными типами аргументов или повреждением данных, всегда вызываются.

Пользовательский extraction filters должен поднимать FilterError для фатальных ошибок и ExtractError для нефатальных.

Обратите внимание, что при возникновении исключения архив может быть частично извлечен. Ответственность за очистку лежит на пользователе.

TarFile.extraction_filter

Added in version 3.12.

Значение extraction filter используется по умолчанию для аргументов фильтра extract() и extractall().

Атрибут может быть None или вызываемым. Строковые имена для этого атрибута не допускаются, в отличие от аргумента filter в extract().

Если extraction_filter равен None (по умолчанию), вызов метода извлечения без аргумента фильтр вызовет ошибку DeprecationWarning и вернется к фильтру fully_trusted, опасное поведение которого соответствует предыдущим версиям Python.

В Python 3.14+, если оставить extraction_filter=None, методы извлечения будут по умолчанию использовать фильтр data.

Атрибут может быть установлен для экземпляров или переопределен в подклассах. Также можно установить его на сам класс TarFile, чтобы задать глобальное значение по умолчанию, хотя, поскольку это влияет на все использования tarfile, лучше всего делать это только в приложениях верхнего уровня или site configuration. Чтобы установить глобальное значение по умолчанию таким образом, функцию фильтрации нужно обернуть в staticmethod(), чтобы предотвратить введение аргумента self.

TarFile.add(name, arcname=None, recursive=True, *, filter=None)

Добавьте файл name в архив. name может быть файлом любого типа (каталог, fifo, символическая ссылка и т.д.). Если задано, arcname указывает альтернативное имя файла в архиве. По умолчанию каталоги добавляются рекурсивно. Этого можно избежать, установив для параметра recursive значение False. Рекурсия добавляет записи в отсортированном порядке. Если задан filter, то это должна быть функция, которая принимает аргумент TarInfo и возвращает измененный объект TarInfo. Если вместо этого возвращается None, то объект TarInfo будет исключен из архива. Пример см. в разделе Примеры.

Изменено в версии 3.2: Добавлен параметр фильтр.

Изменено в версии 3.7: Рекурсия добавляет записи в отсортированном порядке.

TarFile.addfile(tarinfo, fileobj=None)

Добавляет в архив TarInfo объект tarinfo. Если tarinfo представляет собой обычный файл ненулевого размера, аргумент fileobj должен быть binary file, из него считываются tarinfo.size байта и добавляются в архив. Вы можете создавать объекты TarInfo напрямую или с помощью gettarinfo().

Изменено в версии 3.13: Для обычных файлов ненулевого размера необходимо указать fileobj.

TarFile.gettarinfo(name=None, arcname=None, fileobj=None)

Создайте объект TarInfo из результата выполнения os.stat() или эквивалентного действия над существующим файлом. Файл либо именуется name, либо указывается как file object fileobj с дескриптором файла. name может быть path-like object. Если задано, arcname указывает альтернативное имя файла в архиве, в противном случае имя берется из атрибута name fileobj или аргумента name. Имя должно быть текстовой строкой.

Вы можете изменить некоторые атрибуты TarInfo перед его добавлением с помощью addfile(). Если объект файла не является обычным файловым объектом, расположенным в начале файла, могут потребоваться изменения таких атрибутов, как size. Это относится к таким объектам, как GzipFile. Атрибут name также может быть изменен, и в этом случае arcname может быть фиктивной строкой.

Изменено в версии 3.6: Параметр name принимает значение path-like object.

TarFile.close()

Закройте TarFile. В режиме записи в архив добавляются два завершающих нулевых блока.

TarFile.pax_headers: dict

Словарь, содержащий пары ключ-значение глобальных заголовков pax.

Объекты TarInfo

Объект TarInfo представляет один член в TarFile. Помимо хранения всех необходимых атрибутов файла (таких как тип файла, размер, время, права доступа, владелец и т. д.), он предоставляет несколько полезных методов для определения его типа. Он не содержит самих данных файла.

Объекты TarInfo возвращаются методами TarFile getmember(), getmembers() и gettarinfo().

Модификация объектов, возвращаемых методами getmember() или getmembers(), повлияет на все последующие операции с архивом. Для случаев, когда это нежелательно, можно использовать copy.copy() или вызвать метод replace(), чтобы создать измененную копию за один шаг.

Некоторые атрибуты могут быть установлены в None, чтобы указать, что часть метаданных не используется или неизвестна. Различные методы TarInfo по-разному обрабатывают None:

  • Методы extract() или extractall() будут игнорировать соответствующие метаданные, оставляя их установленными по умолчанию.

  • addfile() не удастся.

  • list() выведет строку-заготовку.

class tarfile.TarInfo(name='')

Создайте объект TarInfo.

classmethod TarInfo.frombuf(buf, encoding, errors)

Создайте и верните объект TarInfo из строкового буфера buf.

Вызывает HeaderError, если буфер недействителен.

classmethod TarInfo.fromtarfile(tarfile)

Прочитайте следующий член из TarFile объекта tarfile и верните его как TarInfo объект.

TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')

Создает строковый буфер из объекта TarInfo. Информацию об аргументах см. в конструкторе класса TarFile.

Изменено в версии 3.2: Используйте 'surrogateescape' в качестве значения по умолчанию для аргумента errors.

Объект TarInfo имеет следующие атрибуты открытых данных:

TarInfo.name: str

Имя члена архива.

TarInfo.size: int

Размер в байтах.

TarInfo.mtime: int | float

Время последней модификации в секундах с момента epoch, как в os.stat_result.st_mtime.

Изменено в версии 3.12: Может быть установлено значение None для extract() и extractall(), в результате чего извлечение не будет применять этот атрибут.

TarInfo.mode: int

Биты разрешения, как для os.chmod().

Изменено в версии 3.12: Может быть установлено значение None для extract() и extractall(), в результате чего извлечение не будет применять этот атрибут.

TarInfo.type

Тип файла. Тип обычно является одной из этих констант: REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE. Для более удобного определения типа объекта TarInfo используйте приведенные ниже методы is*().

TarInfo.linkname: str

Имя целевого файла, которое присутствует только в объектах TarInfo типа LNKTYPE и SYMTYPE.

Для символических ссылок (SYMTYPE) имя ссылки указывается относительно каталога, содержащего ссылку. Для жестких ссылок (LNKTYPE) имя ссылки относительно корня архива.

TarInfo.uid: int

Идентификатор пользователя, который первоначально сохранил этого участника.

Изменено в версии 3.12: Может быть установлено значение None для extract() и extractall(), в результате чего извлечение не будет применять этот атрибут.

TarInfo.gid: int

Идентификатор группы пользователя, который первоначально сохранил этого участника.

Изменено в версии 3.12: Может быть установлено значение None для extract() и extractall(), в результате чего извлечение не будет применять этот атрибут.

TarInfo.uname: str

Имя пользователя.

Изменено в версии 3.12: Может быть установлено значение None для extract() и extractall(), в результате чего извлечение не будет применять этот атрибут.

TarInfo.gname: str

Название группы.

Изменено в версии 3.12: Может быть установлено значение None для extract() и extractall(), в результате чего извлечение не будет применять этот атрибут.

TarInfo.chksum: int

Контрольная сумма заголовка.

TarInfo.devmajor: int

Основной номер устройства.

TarInfo.devminor: int

Минорный номер устройства.

TarInfo.offset: int

Заголовок tar начинается здесь.

TarInfo.offset_data: int

Данные файла начинаются здесь.

TarInfo.sparse

Скудная информация о членах.

TarInfo.pax_headers: dict

Словарь, содержащий пары ключ-значение связанного расширенного заголовка pax.

TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., uid=..., gid=..., uname=..., gname=..., deep=True)

Added in version 3.12.

Возвращает новую копию объекта TarInfo с измененными заданными атрибутами. Например, чтобы вернуть TarInfo с именем группы, установленным в 'staff', используйте:

new_tarinfo = old_tarinfo.replace(gname='staff')

По умолчанию создается глубокая копия. Если значение deep равно false, копия будет неглубокой, т. е. pax_headers и все пользовательские атрибуты будут использоваться совместно с исходным объектом TarInfo.

Объект TarInfo также предоставляет несколько удобных методов запроса:

TarInfo.isfile()

Возвращает True, если объект TarInfo является обычным файлом.

TarInfo.isreg()

То же, что и isfile().

TarInfo.isdir()

Верните True, если это каталог.

TarInfo.issym()

Верните True, если это символическая ссылка.

TarInfo.islnk()

Верните True, если это жесткая ссылка.

TarInfo.ischr()

Верните True, если это символьное устройство.

TarInfo.isblk()

Верните True, если это блочное устройство.

TarInfo.isfifo()

Верните True, если это FIFO.

TarInfo.isdev()

Верните True, если это одно из символьных устройств, блочное устройство или FIFO.

Фильтры для извлечения

Added in version 3.12.

Формат tar предназначен для передачи всех деталей UNIX-подобной файловой системы, что делает его очень мощным. К сожалению, эти возможности позволяют легко создавать tar-файлы, которые при извлечении приводят к непредусмотренным - и, возможно, вредоносным - последствиям. Например, при извлечении tar-файла можно перезаписать произвольные файлы различными способами (например, используя абсолютные пути, компоненты пути .. или симлинки, которые влияют на последующие члены).

В большинстве случаев полная функциональность не нужна. Поэтому tarfile поддерживает фильтры извлечения: механизм, позволяющий ограничить функциональность и тем самым смягчить некоторые проблемы безопасности.

См.также

PEP 706

Содержит дополнительную мотивацию и обоснование дизайна.

Аргумент фильтр для TarFile.extract() или extractall() может быть:

  • строка 'fully_trusted': Соблюдать все метаданные, указанные в архиве. Следует использовать, если пользователь полностью доверяет архиву или реализует собственную сложную проверку.

  • строка 'tar': Разрешить большинство tar-специфических функций (т.е. функций UNIX-подобных файловых систем), но блокировать функции, которые с большой вероятностью могут оказаться неожиданными или вредоносными. Подробности см. в разделе tar_filter().

  • строка 'data': Игнорировать или блокировать большинство функций, характерных для UNIX-подобных файловых систем. Предназначен для извлечения кроссплатформенных архивов данных. Подробности см. в разделе data_filter().

  • None (по умолчанию): Использовать TarFile.extraction_filter.

    Если он также равен None (по умолчанию), вызовите DeprecationWarning и вернитесь к фильтру 'fully_trusted', опасное поведение которого соответствует предыдущим версиям Python.

    В Python 3.14 фильтр 'data' будет использоваться по умолчанию. Можно перейти и раньше; смотрите TarFile.extraction_filter.

  • Вызываемый объект, который будет вызываться для каждого извлеченного члена с TarInfo, описывающим член и путь назначения к месту извлечения архива (т.е. один и тот же путь используется для всех членов):

    filter(member: TarInfo, path: str, /) -> TarInfo | None
    

    Вызывается непосредственно перед извлечением каждого члена, чтобы учесть текущее состояние диска. Она может:

    • возвращает объект TarInfo, который будет использоваться вместо метаданных в архиве, или

    • возвращает None, в этом случае член будет пропущен, или

    • поднять исключение, чтобы прервать операцию или пропустить член, в зависимости от errorlevel. Обратите внимание, что при прерывании извлечения extractall() может оставить архив частично извлеченным. Он не пытается очистить архив.

Именованные фильтры по умолчанию

Предварительно созданные фильтры с именами доступны в виде функций, поэтому их можно повторно использовать в пользовательских фильтрах:

tarfile.fully_trusted_filter(member, path)

Верните член без изменений.

Это реализует фильтр 'fully_trusted'.

tarfile.tar_filter(member, path)

Реализует фильтр 'tar'.

  • Удалите из имен файлов ведущие косые черты (/ и os.sep).

  • Refuse для извлечения файлов с абсолютными путями (в случае, если имя является абсолютным даже после удаления косых черт, например, C:/foo в Windows). Это повышает AbsolutePathError.

  • Refuse для извлечения файлов, абсолютный путь которых (после перехода по симлинкам) окажется за пределами места назначения. Это приводит к появлению OutsideDestinationError.

  • Очистите биты высокого режима (setuid, setgid, sticky) и биты групповой/прочей записи (S_IWGRP | S_IWOTH).

Возвращает измененный член TarInfo.

tarfile.data_filter(member, path)

Реализует фильтр 'data'. В дополнение к тому, что делает tar_filter:

  • Refuse для извлечения ссылок (жестких или мягких), которые ссылаются на абсолютные пути, или тех, которые ссылаются за пределы пункта назначения.

    При этом поднимается AbsoluteLinkError или LinkOutsideDestinationError.

    Обратите внимание, что такие файлы не принимаются даже на платформах, не поддерживающих символические ссылки.

  • Refuse для извлечения файлов устройств (включая трубы). Это повышает SpecialFileError.

  • Для обычных файлов, включая жесткие ссылки:

    • Установите права владельца на чтение и запись (S_IRUSR | S_IWUSR).

    • Снимите групповые и другие исполняемые права (S_IXGRP | S_IXOTH), если у владельца их нет (S_IXUSR).

  • Для других файлов (каталогов) установите mode в None, чтобы методы извлечения пропускали применение битов разрешения.

  • Установите информацию о пользователях и группах (uid, gid, uname, gname) в значение None, чтобы методы извлечения пропускали ее установку.

Возвращает измененный член TarInfo.

Ошибки фильтрации

Когда фильтр отказывается извлекать файл, он поднимает соответствующее исключение, подкласс FilterError. Это прервет извлечение, если TarFile.errorlevel равно 1 или больше. При значении errorlevel=0 ошибка будет занесена в журнал, член будет пропущен, но извлечение продолжится.

Подсказки для дальнейшей проверки

Даже при значении filter='data' tarfile не подходит для извлечения недоверенных файлов без предварительной проверки. Помимо прочего, предустановленные фильтры не предотвращают атаки типа «отказ в обслуживании». Пользователям следует выполнять дополнительные проверки.

Вот неполный список того, что нужно учесть:

  • Извлеките в new temporary directory, чтобы предотвратить, например, использование ранее существовавших ссылок и облегчить очистку после неудачного извлечения.

  • При работе с недоверенными данными используйте внешние (например, на уровне ОС) ограничения на использование диска, памяти и процессора.

  • Проверка имен файлов на соответствие списку разрешенных символов (для отсеивания управляющих символов, путаницы, иностранных разделителей путей и т.д.).

  • Убедитесь, что имена файлов имеют ожидаемые расширения (не рекомендуется использовать файлы, которые выполняются при нажатии на них, или файлы без расширений, например имена специальных устройств Windows).

  • Ограничьте количество извлекаемых файлов, общий размер извлекаемых данных, длину имен файлов (включая длину симлинков) и размер отдельных файлов.

  • Проверьте наличие файлов, которые будут затенены в файловых системах с нечувствительным регистром.

Также обратите внимание на то, что:

  • Файлы Tar могут содержать несколько версий одного и того же файла. Предполагается, что более поздние версии будут перезаписывать все более ранние. Эта функция очень важна для обновления ленточных архивов, но может быть использована с целью злоупотребления.

  • tarfile не защищает от проблем с «живыми» данными, например, от действий злоумышленника, который вмешивается в каталог назначения (или источника) во время извлечения (или архивирования).

Поддержка старых версий Python

Фильтры извлечения были добавлены в Python 3.12, но могут быть перенесены в более ранние версии в виде обновлений безопасности. Чтобы проверить, доступна ли функция, используйте, например, hasattr(tarfile, 'data_filter'), а не проверяйте версию Python.

В следующих примерах показано, как поддерживать версии Python с этой функцией и без нее. Обратите внимание, что установка extraction_filter повлияет на все последующие операции.

  • Полностью доверенный архив:

    my_tarfile.extraction_filter = (lambda member, path: member)
    my_tarfile.extractall()
    
  • Используйте фильтр 'data', если он доступен, но вернитесь к поведению Python 3.11 ('fully_trusted'), если эта функция недоступна:

    my_tarfile.extraction_filter = getattr(tarfile, 'data_filter',
                                           (lambda member, path: member))
    my_tarfile.extractall()
    
  • Используйте фильтр 'data'; неудача, если он недоступен:

    my_tarfile.extractall(filter=tarfile.data_filter)
    

    или:

    my_tarfile.extraction_filter = tarfile.data_filter
    my_tarfile.extractall()
    
  • Используйте фильтр 'data'; предупредите, если он недоступен:

    if hasattr(tarfile, 'data_filter'):
        my_tarfile.extractall(filter='data')
    else:
        # remove this when no longer needed
        warn_the_user('Extracting may be unsafe; consider updating Python')
        my_tarfile.extractall()
    

Пример фильтра извлечения с учетом состояния

В то время как методы извлечения tarfile используют простой вызываемый filter, пользовательские фильтры могут быть более сложными объектами с внутренним состоянием. Может быть полезно записать их в виде менеджеров контекста, которые можно использовать следующим образом:

with StatefulFilter() as filter_func:
    tar.extractall(path, filter=filter_func)

Такой фильтр можно записать, например, так:

class StatefulFilter:
    def __init__(self):
        self.file_count = 0

    def __enter__(self):
        return self

    def __call__(self, member, path):
        self.file_count += 1
        return member

    def __exit__(self, *exc_info):
        print(f'{self.file_count} files extracted')

Интерфейс командной строки

Added in version 3.4.

Модуль tarfile предоставляет простой интерфейс командной строки для работы с архивами tar.

Если вы хотите создать новый tar-архив, укажите его имя после опции -c, а затем перечислите имена файлов, которые должны быть включены:

$ python -m tarfile -c monty.tar  spam.txt eggs.txt

Передача каталога также допустима:

$ python -m tarfile -c monty.tar life-of-brian_1979/

Если вы хотите распаковать tar-архив в текущий каталог, используйте опцию -e:

$ python -m tarfile -e monty.tar

Вы также можете распаковать tar-архив в другую директорию, передав имя директории:

$ python -m tarfile -e monty.tar  other-dir/

Чтобы получить список файлов в tar-архиве, используйте опцию -l:

$ python -m tarfile -l monty.tar

Параметры командной строки

-l <tarfile>
--list <tarfile>

Список файлов в tar-файле.

-c <tarfile> <source1> ... <sourceN>
--create <tarfile> <source1> ... <sourceN>

Создайте tar-файл из исходных файлов.

-e <tarfile> [<output_dir>]
--extract <tarfile> [<output_dir>]

Распаковать tarfile в текущий каталог, если output_dir не указан.

-t <tarfile>
--test <tarfile>

Проверьте, является ли tar-файл действительным или нет.

-v, --verbose

Подробный вывод.

--filter <filtername>

Определяет фильтр для --extract. Подробности см. в разделе Фильтры для извлечения. Принимаются только строковые имена (то есть fully_trusted, tar и data).

Примеры

Как извлечь весь tar-архив в текущий рабочий каталог:

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall(filter='data')
tar.close()

Как извлечь подмножество tar-архива с TarFile.extractall(), используя функцию-генератор вместо списка:

import os
import tarfile

def py_files(members):
    for tarinfo in members:
        if os.path.splitext(tarinfo.name)[1] == ".py":
            yield tarinfo

tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()

Как создать несжатый tar-архив из списка имен файлов:

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
    tar.add(name)
tar.close()

Тот же пример с использованием оператора with:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

Как прочитать сжатый gzip-архив tar и отобразить информацию о его участниках:

import tarfile
tar = tarfile.open("sample.tar.gz", "r:gz")
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.")
tar.close()

Как создать архив и сбросить информацию о пользователе с помощью параметра filter в TarFile.add():

import tarfile
def reset(tarinfo):
    tarinfo.uid = tarinfo.gid = 0
    tarinfo.uname = tarinfo.gname = "root"
    return tarinfo
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add("foo", filter=reset)
tar.close()

Поддерживаемые форматы tar

Существует три формата tar, которые можно создать с помощью модуля tarfile:

  • Формат POSIX.1-1988 ustar (USTAR_FORMAT). Он поддерживает имена файлов длиной максимум 256 символов и имена ссылок длиной до 100 символов. Максимальный размер файла - 8 Гб. Это старый и ограниченный, но широко поддерживаемый формат.

  • Формат GNU tar (GNU_FORMAT). Поддерживает длинные имена файлов и имена ссылок, файлы размером более 8 Гб и разреженные файлы. Является стандартом де-факто в системах GNU/Linux. tarfile полностью поддерживает расширения GNU tar для длинных имен, поддержка разреженных файлов доступна только для чтения.

  • Формат POSIX.1-2001 pax (PAX_FORMAT). Это самый гибкий формат, практически не имеющий ограничений. Он поддерживает длинные имена файлов и ссылок, большие файлы и переносимо хранит имена путей. Современные реализации tar, включая GNU tar, bsdtar/libarchive и star, полностью поддерживают расширенные возможности pax; некоторые старые или не поддерживаемые библиотеки могут этого не делать, но должны обращаться с архивами pax так, как если бы они были в универсально поддерживаемом формате ustar. Это текущий формат по умолчанию для новых архивов.

    Он расширяет существующий формат ustar дополнительными заголовками для информации, которая не может быть сохранена иным способом. Существует два вида заголовков pax: Расширенные заголовки влияют только на заголовок последующего файла, глобальные заголовки действительны для всего архива и влияют на все последующие файлы. Все данные в заголовке pax кодируются в UTF-8 для удобства переноса.

Есть еще несколько вариантов формата tar, которые можно прочитать, но нельзя создать:

  • Древний формат V7. Это первый формат tar из Unix Seventh Edition, хранящий только обычные файлы и каталоги. Имена не должны быть длиннее 100 символов, нет информации об именах пользователей/групп. В некоторых архивах неправильно подсчитываются контрольные суммы заголовков в случае полей, содержащих не ASCII-символы.

  • Расширенный формат tar для SunOS. Этот формат является вариантом формата POSIX.1-2001 pax, но не является совместимым.

Проблемы с юникодом

Изначально формат tar был задуман для создания резервных копий на ленточных накопителях с основным упором на сохранение информации о файловой системе. В настоящее время tar-архивы широко используются для распространения файлов и обмена архивами по сети. Одной из проблем оригинального формата (на котором основаны все остальные форматы) является отсутствие концепции поддержки различных кодировок символов. Например, обычный архив tar, созданный в системе UTF-8, не может быть корректно прочитан в системе Latin-1, если он содержит символы, отличные от ASCII. Текстовые метаданные (например, имена файлов, имена ссылок, имена пользователей/групп) будут выглядеть поврежденными. К сожалению, не существует способа автоматического определения кодировки архива. Формат pax был разработан для решения этой проблемы. Он хранит метаданные, отличные от ASCII, используя универсальную кодировку UTF-8.

Детали преобразования символов в tarfile контролируются аргументами encoding и errors класса TarFile.

encoding определяет кодировку символов, которую следует использовать для метаданных в архиве. По умолчанию используется значение sys.getfilesystemencoding() или 'ascii' в качестве запасного варианта. В зависимости от того, читается или записывается архив, метаданные должны быть либо декодированы, либо закодированы. Если значение encoding не задано должным образом, преобразование может завершиться неудачей.

Аргумент errors определяет, как будут обрабатываться символы, которые не могут быть преобразованы. Возможные значения перечислены в разделе Обработчики ошибок. По умолчанию используется схема 'surrogateescape', которую Python также использует для вызовов файловой системы, см. раздел Имена файлов, аргументы командной строки и переменные среды.

Для архивов PAX_FORMAT (по умолчанию) encoding обычно не требуется, поскольку все метаданные хранятся с использованием UTF-8. encoding используется только в редких случаях, когда декодируются двоичные заголовки pax или когда хранятся строки с суррогатными символами.