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

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

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

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

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

  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 Ответ

1 голос
/ 29 февраля 2012

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

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

Во-вторых:

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

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

...