Spec-Zone.ru › Python 3.11

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).
  • работает с каталогами, обычными файлами, жёсткими ссылками, символическими ссылками, FIFO, символьными и блочными устройствами, а также может получать и восстанавливать сведения о файлах, такие как временная метка, права доступа и владелец.

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

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' невозможно. Если mode не подходит для чтения определённого (сжатого) файла, вызывается исключение ReadError. Чтобы избежать этого, используйте mode 'r'. Если метод сжатия не поддерживается, вызывается исключение CompressionError.

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

Для режимов 'w:gz', 'r:gz', 'w:bz2', 'r:bz2', 'x:gz', 'x: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 принимает объект, подобный пути.

класс 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

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

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

tarfile.ENCODING

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

tarfile.REGTYPE
tarfile.AREGTYPE

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

tarfile.LNKTYPE

Тип ссылки (внутри tar-файла) 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.

tarfile.GNUTYPE_LONGLINK

Тип длинной ссылки GNU tar 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: Формат по умолчанию для новых архивов изменён с 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)

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

name — путь к архиву. name может быть объектом, представляющим путь. Его можно не указывать, если задан 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 задают кодировку символов, используемую для чтения или записи архива, и способ обработки ошибок преобразования. Значения по умолчанию подходят большинству пользователей. Подробные сведения см. в разделе Проблемы Unicode.

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

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

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

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

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 из tarfile. В противном случае используются имена, указанные в tarfile.

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

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

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

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

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

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

Изменено в версии 3.11.4: Добавлен параметр 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.11.4: Добавлен параметр filter.

TarFile.extractfile(member)

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

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

TarFile.errorlevel: int

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

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

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

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

TarFile.extraction_filter

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

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

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

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

В Python 3.12 и новее, если оставить extraction_filter=None, будет выдано предупреждение DeprecationWarning.

В 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 в архив. Если задан fileobj, это должен быть двоичный файл; из него считываются tarinfo.size байт и добавляются в архив. Объекты TarInfo можно создавать напрямую или с помощью метода gettarinfo().

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() выведет строку-заполнитель.

Изменено в версии 3.11.4: Добавлен метод replace() и обработка None.

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

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

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

TarInfo.mode: int

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

Изменено в версии 3.11.4: Для методов 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.11.4: Для методов extract() и extractall() можно задать значение None; в этом случае при извлечении этот атрибут не применяется.

TarInfo.gid: int

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

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

TarInfo.uname: str

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

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

TarInfo.gname: str

Имя группы.

Изменено в версии 3.11.4: Для методов 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.11.4.

Возвращает новую копию объекта 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.11.4.

Формат 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 (значение по умолчанию), будет использоваться фильтр 'fully_trusted' (для совместимости с предыдущими версиями Python).

    В Python 3.12 будет выдаваться DeprecationWarning.

    В 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, он:

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

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

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

  • отказывает в извлечении файлов устройств (включая каналы). Вызывает исключение 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')

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

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

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

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

Примеры

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

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
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

С помощью модуля 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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/tarfile.html

Spec-Zone.ru

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