2009-11-24 9 views
6

Mi formulario de carga espera un archivo tar y quiero verificar si los datos cargados son válidos. El módulo tarfile es compatible con 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.¿Cómo determinar si los datos son archivos tar válidos sin un archivo?

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

Respuesta

3

Supongamos que los datos cargados se encuentran en la cadena data.

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 archivo tar y la compresión. Más información está disponible en la documentación tarfile.

+0

Esto plantea la pregunta: ¿Admite el módulo tarfile de Python los diferentes formatos de alquitrán de los que está hablando con is_tarfile() al verificar archivos directamente? – Shule

+2

@Shule Para responder a esta pregunta, puede echar un vistazo al código fuente del módulo para ['is_tarfile()'] (https://hg.python.org/cpython/file/2.7/Lib/tarfile.py#l2616) . – mhawke

4

El formato de archivo tar es here en Wikipedia.

Sospecho que su mejor opción sería verificar que la suma de comprobación del encabezado para el primer archivo sea válida. También es posible que desee comprobar el nombre del archivo para la cordura, pero que puede no ser confiable, dependiendo de los nombres de archivo 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 suma de comprobación se calcula tomando la suma de los valores de byte sin signo del bloque de cabecera con los ocho bytes de suma de comprobación adoptadas para ser espacios ASCII (valor decimal 32)

Se almacena como un número octal de seis dígitos con ceros a la izquierda seguidos por un valor nulo y luego un espacio.

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

Los lectores deben calcular la suma de comprobación de ambas maneras, y tratarla como buena si la suma con o sin signo coincide con la suma de comprobación incluida.

También está el formato Ustar (también se detalla en ese enlace), pero, ya que es una extensión del formato tar edad, el método detallado anteriormente debería seguir funcionando. UStar generalmente solo almacena información adicional sobre cada archivo.

Como alternativa, dado que Python es de código abierto, se puede ver cómo funciona el is_tarfile y comprobar la transmisión en lugar de un archivo. El código fuente está disponible here bajo Python-3.1.1/Lib/tarfile.py pero no es para corazones débiles :-)

+0

¿Existe alguna convención para codificar nombres de archivos que no sean ASCII? Ese artículo menciona el problema, pero no menciona una solución. –

3

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 paxdiablo mensaje: alquitrán es un formato de archivo muy difícil y compleja, a pesar de su aparente simplicidad. Puede verificar la restricción básica, pero si debe admitir todos los posibles dialectos tar, perderá mucho tiempo. La mayor parte de su complejidad proviene de las siguientes cuestiones:

  • ausencia de un estándar real hasta un estándar de facto existía (Ustar/pax)
  • agujeros en la especificación dejando vendedores zonas grises donde cada uno su propio orden solución
  • vendedores diciendo "nuestro alquitrán es mejor, y tomará control del mundo t3h"
  • limitaciones y soluciones para estas limitaciones (por ejemplo,longitud de nombre de archivo)

Además, hay formato no tiene encabezado por adelantado, por lo que la única manera de comprobar si todo el archivo está cuerdo es escanear el archivo completo, coger cada registro, y validar cada uno.

+0

ah, me has vencido por medio minuto :-) –

+0

en realidad, tu método es otra (probablemente mejor) forma de lograr lo mismo. –

3

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

Cuestiones relacionadas