files con comprimir compress archivos python compression zip tar rar

con - python unzip file



Python-mecanismo para identificar el tipo de archivo comprimido y descomprimir (5)

"a" es completamente falso.

"b" se puede interpretar mal mal, ya que ".zip" no significa que el archivo sea en realidad un archivo zip. Podría ser un JPEG con extensión zip (para fines confusos, si lo desea).

Realmente necesita verificar si los datos dentro del archivo coinciden con los datos que se espera que tengan por extensión. También echa un vistazo a byte mágico .

Un archivo comprimido se puede clasificar en los siguientes grupos lógicos
a. El sistema operativo en el que está trabajando (* ix, Win) etc.
segundo. Diferentes tipos de algoritmos de compresión (es decir, .zip, .Z, .bz2, .rar, .gzip). Al menos a partir de una lista estándar de archivos comprimidos utilizados en su mayoría.
do. Luego tenemos el mecanismo de la bola de alquitrán, donde supongo que no hay compresión. Pero actúa más como una concatenación.

Ahora, si empezamos a abordar el conjunto anterior de archivos comprimidos,
a. La opción (a) sería atendida por Python ya que es un lenguaje independiente de la plataforma.
segundo. La opción (b) y (c) parece tener un problema.

Qué necesito
¿Cómo identifico el tipo de archivo (tipo de compresión) y luego los descomprimo?

Me gusta:

fileType = getFileType(fileName) switch(fileType): case .rar: unrar.... case .zip: unzip.... etc

Entonces, la pregunta fundamental es ¿cómo identificamos el algoritmo de compresión basado en el archivo (suponiendo que la extensión no esté provista o sea incorrecta)? ¿Hay alguna forma específica de hacerlo en python?


Basado en la respuesta de lazyr y mi comentario, esto es lo que quiero decir:

class CompressedFile (object): magic = None file_type = None mime_type = None proper_extension = None def __init__(self, f): # f is an open file or file like object self.f = f self.accessor = self.open() @classmethod def is_magic(self, data): return data.startswith(self.magic) def open(self): return None import zipfile class ZIPFile (CompressedFile): magic = ''/x50/x4b/x03/x04'' file_type = ''zip'' mime_type = ''compressed/zip'' def open(self): return zipfile.ZipFile(self.f) import bz2 class BZ2File (CompressedFile): magic = ''/x42/x5a/x68'' file_type = ''bz2'' mime_type = ''compressed/bz2'' def open(self): return bz2.BZ2File(self.f) import gzip class GZFile (CompressedFile): magic = ''/x1f/x8b/x08'' file_type = ''gz'' mime_type = ''compressed/gz'' def open(self): return gzip.GzipFile(self.f) # factory function to create a suitable instance for accessing files def get_compressed_file(filename): with file(filename, ''rb'') as f: start_of_file = f.read(1024) f.seek(0) for cls in (ZIPFile, BZ2File, GZFile): if cls.is_magic(start_of_file): return cls(f) return None filename=''test.zip'' cf = get_compressed_file(filename) if cf is not None: print filename, ''is a'', cf.mime_type, ''file'' print cf.accessor

Ahora puede acceder a los datos comprimidos usando cf.accessor . Todos los módulos proporcionan métodos similares como ''read ()'', ''write ()'', etc. para hacer esto.


Esta es una pregunta compleja que depende de una serie de factores: el más importante es cuán portátil debe ser su solución.

Lo básico para encontrar el tipo de archivo dado a un archivo es encontrar un encabezado de identificación en el archivo, generalmente algo llamado "secuencia mágica" o encabezado de firma , que identifica que un archivo es de cierto tipo. Su nombre o extensión generalmente no se usa si se puede evitar. Para algunos archivos, Python tiene esto incorporado. Por ejemplo, para tratar con archivos .tar , puede usar el módulo tarfile , que tiene un método conveniente is_tarfile . Hay un módulo similar llamado zipfile . Estos módulos también te permitirán extraer archivos en Python puro.

Por ejemplo:

f = file(''myfile'',''r'') if zipfile.is_zipfile(f): zip = zipfile.ZipFile(f) zip.extractall(''/dest/dir'') elif tarfile.is_tarfile(f): ...

Si su solución es solo para Linux o OSX, también existe el comando de file que hará mucho del trabajo por usted. También puede usar las herramientas integradas para descomprimir los archivos. Si solo está haciendo un script simple, este método es más simple y le dará un mejor rendimiento.


Si el ejercicio es identificarlo solo para etiquetar archivos, tiene muchas respuestas. Si desea descomprimir el archivo, ¿por qué no intenta detectar las ejecuciones / errores? Por ejemplo:

>>> tarfile.is_tarfile(''lala.txt'') False >>> zipfile.is_zipfile(''lala.txt'') False >>> with bz2.BZ2File(''startup.bat'',''r'') as f: ... f.read() ... Traceback (most recent call last): File "<stdin>", line 2, in <module> IOError: invalid data stream


Esta página tiene una lista de firmas de archivos "mágicos". Toma las que necesites y ponlas en un dict como abajo. Luego necesitamos una función que coincida con las teclas dict con el inicio del archivo. He escrito una sugerencia, aunque puede optimizarse preprocesando el magic_dict en, por ejemplo, una regexp compilada gigante.

magic_dict = { "/x1f/x8b/x08": "gz", "/x42/x5a/x68": "bz2", "/x50/x4b/x03/x04": "zip" } max_len = max(len(x) for x in magic_dict) def file_type(filename): with open(filename) as f: file_start = f.read(max_len) for magic, filetype in magic_dict.items(): if file_start.startswith(magic): return filetype return "no match"

Esta solución debe ser multiplataforma y, por supuesto, no depende de la extensión del nombre del archivo, pero puede dar falsos positivos para archivos con contenido aleatorio que simplemente comienzan con algunos bytes mágicos específicos.