Как я могу прочитать из поврежденного файла tar.bz2 в Python?

У меня есть программа, которая сохраняет свой вывод в файл tar.bz2, как он работает. У меня есть скрипт Python, который обрабатывает эти данные.

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

Конечно, последний блок bzip2 еще не закончен, поэтому его невозможно прочитать - он фактически поврежден, хотя на самом деле он просто обрезан. GNU tar на самом деле с радостью извлечет все, что может, из файла до этого момента - как и будет bzcat, в этом отношении. А также bzip2recover может создавать восстановленные блоки, хотя это действительно менее полезно в этом случае, чем bzcat,

Но я пытаюсь использовать стандартный модуль tarfile для Python. Это не с

  File "/usr/lib64/python2.7/tarfile.py", line 2110, in extractfile
    tarinfo = self.getmember(member)
  File "/usr/lib64/python2.7/tarfile.py", line 1792, in getmember
    tarinfo = self._getmember(name)
  File "/usr/lib64/python2.7/tarfile.py", line 2361, in _getmember
    members = self.getmembers()
  File "/usr/lib64/python2.7/tarfile.py", line 1803, in getmembers
    self._load()        # all members, we first have to
  File "/usr/lib64/python2.7/tarfile.py", line 2384, in _load
    tarinfo = self.next()
  File "/usr/lib64/python2.7/tarfile.py", line 2319, in next
    self.fileobj.seek(self.offset)
EOFError: compressed file ended before the logical end-of-stream was detected

когда я пытаюсь использовать TarFile.extractfile на файл, который я знаю, в начале. (tar -xf tarfile.tar.bz2 filename будет извлекать это просто отлично.)

Есть ли что-нибудь умное, что я могу сделать, чтобы игнорировать неверный конец файла и работать с тем, что у меня есть?

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

(Я нашел существующий вопрос архива Untar в Python с ошибками, но в этом случае пользователь пытается os.system файл tar.)

1 ответ

Кажется, есть 2 возможности. Во-первых, и, скорее всего:

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

Во-вторых:

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

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

Другие вопросы по тегам