Spec-Zone.ru › Python 3.13

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

Исходный код: Lib/tarfile.py

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

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

  • чтение и запись сжатых архивов gzip, bz2 и lzma, если доступны соответствующие модули.
  • поддержка чтения и записи в формате POSIX.1-1988 (ustar).
  • поддержка чтения и записи в формате GNU tar, включая расширения longname и longlink; поддержка чтения всех вариантов расширения sparse, включая восстановление разреженных файлов.
  • поддержка чтения и записи в формате POSIX.1-2001 (pax).
  • обработка каталогов, обычных файлов, жёстких ссылок, символических ссылок, каналов FIFO, символьных и блочных устройств, а также получение и восстановление сведений о файлах, таких как временная метка, права доступа и владелец.

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

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

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

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

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

режим

действие

'r' или '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' или 'a:'

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

'w' или 'w:'

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

'w:gz'

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

'w:bz2'

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

'w:xz'

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

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

Если указан fileobj, он используется вместо файлового объекта, открытого в двоичном режиме для 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() (в зависимости от mode), работающим с байтами. Параметр bufsize задаёт размер блока; по умолчанию он равен 20 * 512 байтам. Используйте этот вариант, например, с sys.stdin.buffer, файловым объектом сокета или ленточным устройством. Однако такой объект 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 принимает объект, подобный пути.

Изменено в версии 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

Базовый класс для элементов, отклонённых фильтрами.

tarinfo

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

exception tarfile.AbsolutePathError

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

exception tarfile.OutsideDestinationError

Возникает при отказе извлекать элемент за пределами целевого каталога.

exception tarfile.SpecialFileError

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

exception tarfile.AbsoluteLinkError

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

exception tarfile.LinkOutsideDestinationError

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

exception tarfile.LinkFallbackError

Возникает при отказе эмулировать ссылку (жёсткую или символическую), извлекая другой элемент архива, если этот элемент будет отклонён фильтром из-за расположения. Исключение, возникшее при отклонении заменяющего элемента, доступно как BaseException.__context__.

Добавлено в версии 3.13.4.

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

tarfile.ENCODING

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

tarfile.REGTYPE
tarfile.AREGTYPE

type обычного файла.

tarfile.LNKTYPE

type ссылки (внутри tar-файла).

tarfile.SYMTYPE

type символической ссылки.

tarfile.CHRTYPE

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

tarfile.BLKTYPE

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

tarfile.DIRTYPE

type каталога.

tarfile.FIFOTYPE

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

tarfile.CONTTYPE

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

tarfile.GNUTYPE_LONGNAME

type длинного имени GNU tar.

tarfile.GNUTYPE_LONGLINK

type длинной ссылки GNU tar.

tarfile.GNUTYPE_SPARSE

type разреженного файла GNU tar.

Каждая из следующих констант определяет формат 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: Формат по умолчанию для новых архивов был изменён с GNU_FORMAT на PAX_FORMAT.

См. также

Module zipfile

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

Операции архивации

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

Руководство GNU tar, базовый формат Tar

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

Объекты TarFile

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

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

Добавлено в версии 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 может быть объектом, подобным пути. Его можно не указывать, если задан fileobj. В этом случае используется атрибут name файлового объекта, если он существует.

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

Если задан fileobj, он используется для чтения или записи данных. Если режим fileobj можно определить, он переопределяет mode. 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 определяют кодировку символов, используемую для чтения или записи архива, а также способ обработки ошибок преобразования. Настройки по умолчанию подходят большинству пользователей. Подробную информацию см. в разделе Проблемы с Unicode.

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

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

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

Изменено в версии 3.5: Добавлен режим 'x' (создание исключительно нового файла).

Изменено в версии 3.6: Параметр name принимает объект, подобный пути.

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

classmethod TarFile.open(...)

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

TarFile.getmember(name)

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

Примечание

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

TarFile.getmembers()

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

TarFile.getnames()

Возвращает элементы в виде списка их имён. Порядок имён совпадает с порядком в списке, возвращаемом методом getmembers().

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

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

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

TarFile.next()

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

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

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

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

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

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

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

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

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

Изменено в версии 3.6: Параметр path принимает объект, подобный пути.

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

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

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

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

Примечание

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

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

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

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

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

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

Изменено в версии 3.6: Параметр path принимает объект, подобный пути.

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

TarFile.extractfile(member)

Извлекает элемент из архива в виде файлового объекта. member может быть именем файла или объектом TarInfo. Если member — обычный файл или ссылка, возвращается объект io.BufferedReader. Для всех остальных существующих элементов возвращается None. Если member отсутствует в архиве, возникает исключение 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.

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

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

Обратите внимание: при возникновении исключения архив может быть извлечён лишь частично. Пользователь должен самостоятельно очистить за собой.

TarFile.extraction_filter

Добавлено в версии 3.12.

Фильтр извлечения, используемый по умолчанию для аргумента filter методов extract() и extractall().

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

Если extraction_filter равно None (значение по умолчанию), вызов метода извлечения без аргумента filter вызовет 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: Добавлен параметр filter.

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

TarFile.addfile(tarinfo, fileobj=None)

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

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

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

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

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

Изменено в версии 3.6: Параметр name принимает объект, подобный пути.

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: В качестве значения по умолчанию для аргумента errors используется 'surrogateescape'.

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

TarInfo.name: str

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

TarInfo.size: int

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

TarInfo.mtime: int | float

Время последнего изменения в секундах с начала эпохи, как и в os.stat_result.st_mtime.

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

TarInfo.mode: int

Биты прав доступа, как для os.chmod().

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

TarInfo.type

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

TarInfo.linkname: str

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

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

TarInfo.uid: int

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

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

TarInfo.gid: int

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

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

TarInfo.uname: str

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

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

TarInfo.gname: str

Имя группы.

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

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)

Добавлено в версии 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.

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

Добавлено в версии 3.12.

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

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

См. также

PEP 706

Содержит дополнительные сведения о предпосылках и обосновании выбранного дизайна.

Аргумент filter методов 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)

Возвращает member без изменений.

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

tarfile.tar_filter(member, path)

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

  • Удаляет начальные косые черты (/ и os.sep) из имён файлов.
  • Отказывается извлекать файлы с абсолютными путями (если имя остаётся абсолютным даже после удаления косых черт, например C:/foo в Windows). Вызывает исключение AbsolutePathError.
  • Отказывается извлекать файлы, абсолютный путь которых (после перехода по символическим ссылкам) будет указывать за пределы каталога назначения. Вызывает исключение OutsideDestinationError.
  • Сбрасывает старшие биты режима (setuid, setgid, sticky), а также биты записи для группы и остальных пользователей (S_IWGRP | S_IWOTH).

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

tarfile.data_filter(member, path)

Реализует фильтр 'data'. В дополнение к действиям tar_filter:

  • Нормализует цели ссылок (TarInfo.linkname) с помощью os.path.normpath(). Обратите внимание: при этом удаляются внутренние компоненты .., что может изменить смысл ссылки, если путь в TarInfo.linkname проходит по символическим ссылкам.
  • Отказывается извлекать ссылки (жёсткие или символические), указывающие на абсолютные пути или за пределы каталога назначения.

    Вызывает исключение AbsoluteLinkError или LinkOutsideDestinationError.

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

  • Отказывается извлекать файлы устройств (включая каналы). Вызывает исключение SpecialFileError.
  • Для обычных файлов, включая жёсткие ссылки:

    • Устанавливает права чтения и записи для владельца (S_IRUSR | S_IWUSR).
    • Удаляет права на выполнение для группы и остальных пользователей (S_IXGRP | S_IXOTH), если такие права не установлены для владельца (S_IXUSR).
  • Для остальных файлов (каталогов) устанавливает mode в None, чтобы методы извлечения не применяли биты прав доступа.
  • Устанавливает сведения о пользователе и группе (uid, gid, uname, gname) в None, чтобы методы извлечения не задавали их.

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

Изменено в версии 3.13.4: Цели ссылок теперь нормализуются.

Ошибки фильтров

Если фильтр отказывается извлекать файл, он вызывает соответствующее исключение — подкласс 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')

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

Добавлено в версии 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>]

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

-t <tarfile>
--test <tarfile>

Проверить, является ли архив tar допустимым.

-v, --verbose

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

--filter <filtername>

Задаёт filter для --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, сжатый gzip, и вывести сведения о некоторых его элементах:

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

Примеры записи

Как создать несжатый архив 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)

Как создать архив и записать его в stdout, используя sys.stdout.buffer в параметре fileobj метода TarFile.add():

import sys
import tarfile
with tarfile.open("sample.tar.gz", "w|gz", fileobj=sys.stdout.buffer) as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

Как создать архив и сбросить сведения о пользователе, используя параметр 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

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

  • Формат 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, но несовместим с ним.

Проблемы с Unicode

Формат 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 или сохраняются строки с суррогатными символами.

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/tarfile.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API