¿Cómo determinar si los datos son archivos tar válidos sin un archivo?

Mi formulario de carga espera un archivo tar y quiero comprobar si los datos cargados son válidos. El módulo is_tarfile() admite is_tarfile() , pero espera un nombre de archivo. No quiero desperdiciar recursos escribiendo el archivo en el disco solo para comprobar si es válido.

¿Hay alguna forma de verificar que los datos sean un archivo tar válido sin escribir en el disco, utilizando bibliotecas estándar de Python?

Digamos que sus datos cargados están contenidos en data cadena.

 from tarfile import TarFile, TarError from StringIO import StringIO sio = StringIO(data) try: tf = TarFile(fileobj=sio) # process the file.... except TarError: print "Not a tar file" 

Existen complejidades adicionales, como el manejo de diferentes formatos de archivos tar y la compresión. Más información está disponible en la documentación de tarfile .

El formato de archivo tar está aquí en Wikipedia.

Sospecho que lo mejor sería comprobar que la sum de comprobación del encabezado del primer archivo sea válida. Es posible que también desee verificar el nombre del archivo para ver si está sano, pero puede que no sea confiable, dependiendo de los nombres de los archivos que se han almacenado allí.

Duplicando la información relevante aquí:

 Offset Size Description 0 100 File name 100 8 File mode 108 8 Owner's numeric user ID 116 8 Group's numeric user ID 124 12 File size in bytes 136 12 Last modification time in numeric Unix time format 148 8 Checksum for header block 156 1 Link indicator (file type) 157 100 Name of linked file 

La sum de control se calcula tomando la sum de los valores de bytes sin signo del bloque de encabezado y los ocho bytes de sum de control se consideran espacios ASCII (valor decimal 32).

Se almacena como un número octal de seis dígitos con ceros iniciales seguidos de un nulo y luego un espacio.

Varias implementaciones no se adhieren a esto, por lo que confiar en el primer espacio en blanco recortado de seis dígitos para la sum de comprobación produce una mejor compatibilidad. Además, algunas implementaciones de tar históricas trataron los bytes como firmados.

Los lectores deben calcular la sum de comprobación en ambos sentidos y tratarla como buena si la sum firmada o no firmada coincide con la sum de comprobación incluida.

También está el formato UStar (también detallado en ese enlace) pero, dado que es una extensión del antiguo formato tar, el método detallado anteriormente aún debería funcionar. UStar es generalmente solo para almacenar información adicional sobre cada archivo.

Alternativamente, como Python es de código abierto, puede ver cómo funciona is_tarfile y adaptarlo para verificar su flujo en lugar de un archivo. El código fuente está disponible aquí en Python-3.1.1/Lib/tarfile.py pero no es para los más débiles de corazón 🙂

El método open de tarfile toma un objeto similar a un archivo en su argumento fileObj . Esto puede ser una instancia de StringIO

La clase TarFile acepta un objeto fileobj. Supongo que puede pasar cualquier entidad de descarga parcial que obtenga de su marco web.

 __init__(self, name=None, mode='r', fileobj=None) 

Agregando a la publicación paxdiablo: tar es un formato de archivo muy difícil y complejo, a pesar de su aparente simplicidad. Puede verificar la restricción básica, pero si tiene que soportar todos los posibles dialectos de alquitrán existentes, va a perder mucho tiempo. La mayor parte de su complejidad proviene de los siguientes problemas:

  • ausencia de un estándar real hasta que existiera un estándar de facto (UStar / pax)
  • agujeros en la especificación que dejan a los proveedores áreas grises donde cada uno implementó su propia solución
  • vendedores que dicen “nuestro alquitrán es mejor y se apoderará de t3h world”
  • limitaciones y soluciones para estas limitaciones (por ejemplo, longitud del nombre de archivo)

Además, el formato no tiene encabezado inicial, por lo que la única forma de verificar si todo el archivo está sano es escanear el archivo completamente, capturar cada registro y validar cada uno.