2010-09-13 36 views
20

Tengo un programa de Python que va a tomar los archivos de texto como entrada. Sin embargo, algunos de estos archivos pueden comprimirse gzip.¿Cómo saber si un archivo está comprimido gzip?

¿Existe una multiplataforma, utilizable a partir de Python manera de determinar si un archivo está comprimido con gzip o no?

¿La siguiente fiable o podría un archivo de texto normal 'accidentalmente' mirada gzip-como suficiente para mí para obtener falsos positivos?

try: 
    gzip.GzipFile(filename, 'r') 
    # compressed 
    # ... 
except: 
    # not compressed 
    # ... 
+1

Solo una pequeña sugerencia ... nunca confíe en el final del archivo. Vea la respuesta de hop para saber cómo hacerlo. – helpermethod

+0

@Helper: no estoy seguro (ver mi edición). usted todavía tendría que lidiar con un posible IOError, pero los archivos comprimidos sin el sufijo están rotos, en mi opinión ... llamada difícil :) – hop

Respuesta

34

El magic number para archivos comprimidos gzip es 1f 8b. Aunque las pruebas para esto no son 100% confiables, es muy poco probable que los "archivos de texto normales" comiencen con esos dos bytes, en UTF-8 ni siquiera es legal.

Por lo general, el deporte GZIP archivos comprimido el sufijo .gz sin embargo. Incluso gzip(1) sí mismo no desempaquetará archivos sin él a menos que --force lo haga. Podrías usar eso, pero igual tendrías que lidiar con un posible IOError (que en todo caso tienes que hacer).

Uno de los problemas con su enfoque es, que gzip.GzipFile() no será una excepción si le da de comer un archivo sin comprimir. Solo un read() más tarde lo hará. Esto significa que probablemente deba implementar parte de su lógica de programa dos veces. Feo.

+0

Los archivos comprimidos gzip a menudo tienen la extensión de archivo .gz (de hecho, no creo que alguna vez he visto una extensión .gzip), pero en general no es seguro confiar en la extensión de archivo para probar el tipo de archivo de todos modos. – CanSpice

+0

@CanSpice: por supuesto, error – hop

+0

¿Lo tiene? - La biblioteca gzip C leerá de forma transparente los archivos sin comprimir.Aunque escribirá archivos sin comprimir, pone códigos CRC a través de ellos para permitir "gzip -t" (me sorprendió una vez) –

0

importar el módulo mimetypes. Puede adivinar automáticamente qué tipo de archivo tiene y si está comprimido.

es decir

mimetypes.guess_type('blabla.txt.gz') 

devuelve:

('text/plain', 'gzip')

+12

'mimetypes' solo comprueba el final del nombre del archivo, en realidad no adivina en función del contenido del archivo. – Odinulf

0

no parece funcionar bien en python3 ...

import mimetypes 
filename = "./datasets/test" 

def file_type(filename): 
    type = mimetypes.guess_type(filename) 
    return type 
print(file_type(filename)) 

retornos (Nada, Nada) Pero desde el comando de unix "de archivo"

: ~> conjuntos de datos de archivos/prueba conjuntos de datos/de prueba: datos gzip comprimido, era "iostat_collection", desde Unix, modificada por última vez: Jue Ene 29 07:09:34 2015

+3

mimetypes usa juts el nombre de archivo para adivinar el tipo. Para detectar un tipo de archivo del archivo sin formato, necesitará usar el módulo 'mágico'. –

2

"¿Hay una multiplataforma , utilizable desde Python para determinar si un archivo está comprimido gzip o no? "

La respuesta aceptada me dio el 90% del camino a la solución bastante confiable (prueba si los dos primeros bytes son 1f 8b), pero no mostró cómo hacerlo en Python. Aquí hay una forma posible:

import binascii 

def is_gz_file(filepath): 
    with open(filepath, 'rb') as test_f: 
     return binascii.hexlify(test_f.read(2)) == b'1f8b' 
Cuestiones relacionadas