Spec-Zone.ru › Python 3.12

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' 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', '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

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

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

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)

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

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.

Изменено в версии 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 задаёт способ изменения или отклонения 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 может быть объектом, представляющим путь. Атрибуты файла (владелец, mtime, режим) задаются, если значение set_attrs истинно.

Аргументы 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.

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

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

    При этом вызывается исключение 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).

Примеры

Как извлечь весь архив 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

С помощью модуля 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.12/library/tarfile.html

Spec-Zone.ru

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