2010-09-13 16 views
20

J'ai un programme Python qui va prendre des fichiers texte en entrée. Cependant, certains de ces fichiers peuvent être compressés par gzip.Comment savoir si un fichier est compressé avec gzip?

Existe-t-il une plateforme multiplateforme, utilisable à partir de Python pour déterminer si un fichier est compressé par gzip ou non?

Est-ce que ce qui suit est fiable ou est-ce qu'un fichier texte ordinaire peut sembler "accidentellement" assez ressemblant à un gzip pour que je puisse obtenir des faux positifs?

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

Juste un petit indice ... ne comptez jamais sur la fin du fichier. Voir la réponse du houblon pour savoir comment le faire. – helpermethod

+0

@Helper: je ne suis pas sûr (voir mon édition). vous auriez encore à faire face à un possible IOError, mais les fichiers gzippés sans le suffixe sont cassés, à mon avis ... appel difficile :) – hop

Répondre

34

Le magic number pour les fichiers compressés gzip est 1f 8b. Bien que le test ne soit pas fiable à 100%, il est hautement improbable que les "fichiers texte ordinaires" commencent par ces deux octets - en UTF-8 ce n'est même pas légal.

Habituellement, les fichiers compressés par gzip portent le suffixe .gz. Même gzip(1) lui-même ne décompressera pas les fichiers sans lui, sauf si vous --force à. Vous pourriez peut-être utiliser cela, mais vous devrez quand même faire face à une éventuelle erreur IOError (que vous devez dans tous les cas).

Un problème avec votre approche est que gzip.GzipFile() ne lèvera pas d'exception si vous le chargez un fichier non compressé. Seulement un plus tard read(). Cela signifie que vous devrez probablement implémenter une partie de la logique de votre programme deux fois. Laid.

+0

fichiers compressés gzip ont souvent l'extension de fichier .gz (en fait, je ne pense pas que je 'ai jamais vu une extension .gzip), mais il est généralement dangereux de se fier à l'extension de fichier pour tester le type de fichier de toute façon. – CanSpice

+0

@CanSpice: bien sûr, typo – hop

+0

Le fait? - La bibliothèque gzip C lit de façon transparente les fichiers non compressés.Bien qu'il écrira des fichiers décompressés il met des codes CRC à travers eux pour permettre "gzip -t" (m'a pris une fois) –

0

Importez le module mimetypes. Il peut deviner automatiquement quel type de fichier vous avez, et s'il est compressé.

-à-dire

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

retours:

('text/plain', 'gzip')

+12

'mimetypes' ne vérifie que la fin du nom de fichier, il ne devine pas en fonction du contenu du fichier. – Odinulf

0

ne semble pas fonctionner correctement dans python3 ...

import mimetypes 
filename = "./datasets/test" 

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

renvoie (Aucun, Aucun) Mais à partir de la commande unix "Fichier"

: ~> jeux de données de fichiers/tests jeux de données/test: données compressées gzip, était "iostat_collection", d'Unix, Dernière modification: Jeu Jan 29 07:09:34 2015

+3

mimetypes utilise le nom de fichier pour deviner le type. Pour détecter un type de fichier à partir du fichier brut, vous devrez utiliser le module 'magic'. –

2

« Y at-il un multi-plateforme , utilisable à partir de Python pour déterminer si un fichier est compressé avec gzip ou non? "

La réponse acceptée a obtenu 90% du chemin à la solution assez fiable (test si les deux premiers octets sont 1f 8b), mais n'a pas montré comment faire réellement cela en Python. Voici une façon possible:

import binascii 

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