Comprobando la integridad del archivo tar en Python

Estoy trabajando para convertir mi script de copia de seguridad de shell a Python. Una de las características de mi script anterior era verificar la integridad del archivo tar creado: gzip -t.

Esto parece ser un poco complicado en Python.

Parece que la única forma de hacerlo es leyendo cada uno de los objetos TarInfo comprimidos dentro del archivo tar.

¿Hay alguna forma de verificar la integridad de un archivo tar, sin extraerlo en el disco o guardarlo en la memoria (en su totalidad)?

La gente buena en #python en freenode sugirió que debería leer cada objeto TarInfo parte por parte, descartando cada parte leída.

Debo admitir que no tengo idea de cómo hacer esto, ya que acabo de iniciar Python.

Imagina que tengo un archivo tar de 30 GB que contiene archivos de 1kb a 10GB ...

Esta es la solución que empecé a escribir:

try:
    tardude = tarfile.open("zero.tar.gz")
except:
    print "There was an error opening tarfile. The file might be corrupt or missing."

for member_info in tardude.getmembers():
    try:
        check = tardude.extractfile(member_info.name)
    except:
        print "File: %r is corrupt." % member_info.name

tardude.close()

Este código está lejos de ser terminado. No me atrevería a ejecutar esto en un enorme archivo tar de 30 GB, porque en un momento dado, el control sería un objeto de más de 10 GB (si tengo archivos tan grandes dentro del archivo tar)

Bono: Intenté corromper manualmente zero.tar.gz (editor hexadecimal: edito algunos bytes en el archivo intermedio). La primera, excepto que no captura IOError ... Aquí está la salida:

Traceback (most recent call last):
  File "./test.py", line 31, in <module>
    for member_info in tardude.getmembers():
  File "/usr/lib/python2.7/tarfile.py", line 1805, in getmembers
    self._load()        # all members, we first have to
  File "/usr/lib/python2.7/tarfile.py", line 2380, in _load
    tarinfo = self.next()
  File "/usr/lib/python2.7/tarfile.py", line 2315, in next
    self.fileobj.seek(self.offset)
  File "/usr/lib/python2.7/gzip.py", line 429, in seek
    self.read(1024)
  File "/usr/lib/python2.7/gzip.py", line 256, in read
    self._read(readsize)
  File "/usr/lib/python2.7/gzip.py", line 320, in _read
    self._read_eof()
  File "/usr/lib/python2.7/gzip.py", line 342, in _read_eof
    hex(self.crc)))
IOError: CRC check failed 0xe5384b87 != 0xdfe91e1L

Respuestas a la pregunta(3)

Su respuesta a la pregunta