Comment vérifier le type de fichiers sans extensions en python?

j'ai un dossier plein de fichiers et ceux-ci n'ont pas d'extension. Comment puis-je vérifier les types de fichiers? Je veux vérifier le type de fichier et changer le nom du fichier en conséquence. Supposons une fonction filetype(x) renvoie le type de fichier comme png . Je veux faire ceci:

files = os.listdir(".")
for f in files:
    os.rename(f, f+filetype(f))

Comment faire?

54
demandé sur Hanxue 2012-06-07 22:06:40

7 réponses

il existe des bibliothèques Python qui peuvent reconnaître des fichiers en fonction de leur contenu (généralement un en-tête / numéro magique) et qui ne dépendent pas du nom ou de l'extension du fichier.

si vous vous adressez à de nombreux types de fichiers, vous pouvez utiliser python-magic . C'est juste une reliure Python pour la bibliothèque bien établie magic . Cela a une bonne réputation et (petite approbation) dans l'usage limité que j'en ai fait, il a été solide.

il y a aussi des bibliothèques pour des types de fichiers plus spécialisés. Par exemple, la bibliothèque standard Python a le module imghdr qui fait la même chose juste pour les types de fichiers image.

58
répondu Chris Johnson 2013-09-03 08:27:58

la bibliothèque Python Magic offre les fonctionnalités dont vous avez besoin.

vous pouvez installer la bibliothèque avec pip install python-magic et l'utiliser comme suit:

>>> import magic

>>> magic.from_file('iceland.jpg')
'JPEG image data, JFIF standard 1.01'

>>> magic.from_file('iceland.jpg', mime=True)
'image/jpeg'

>>> magic.from_file('greenland.png')
'PNG image data, 600 x 1000, 8-bit colormap, non-interlaced'

>>> magic.from_file('greenland.png', mime=True)
'image/png'

le code Python dans ce cas appelle libmagic sous le capot, qui est la même bibliothèque utilisée par la commande *NIX file . Ainsi, Cela fait la même chose que les réponses basées sur le sous-processus/shell, mais sans cela généraux.

48
répondu Richard 2014-06-26 14:51:07

sur unix et linux il y a la commande file pour deviner les types de fichiers. Il y a même un "Windows port .

De la l'homme page :

fichier teste chaque argument dans une tentative de le classer. Il y a trois jeux de tests, effectués dans cet ordre: tests du système de fichiers, Nombre Magique tests et tests de langue. Le premier test qui réussit les causes de la type de fichier à imprimer.

vous devez exécuter la commande file avec le module subprocess et ensuite analyser les résultats pour trouver une extension.

edit: Ignore ma réponse. Utilisez plutôt de Chris Johnson.

10
répondu Steven Rumbalski 2017-05-23 10:31:31
import subprocess
p = sub.Popen('file yourfile.txt',stdout=sub.PIPE,stderr=sub.PIPE)
output, errors = p.communicate()
print output

comme Steven l'a souligné, subprocess est le chemin. Vous pouvez obtenir la sortie de commande par la voie ci-dessus comme ce post said

6
répondu xvatar 2017-05-23 11:54:50

vous pouvez également installer la reliure officielle file pour Python, une bibliothèque appelée file-magic (elle n'utilise pas de ctypes, comme python-magic ).

Il est disponible sur PyPI "151960920-fichier" magie et sur Debian comme python-magie . Pour moi, cette bibliothèque est la meilleure à utiliser puisqu'elle est disponible sur PyPI et Debian (et probablement d'autres distributions), ce qui rend le processus de déploiement de votre logiciel plus facile. J'ai blogué sur la façon de l'utiliser , aussi.

5
répondu Álvaro Justen 2017-07-01 08:50:47

dans le cas d'images, vous pouvez utiliser le module imghdr.

>>> import imghdr
>>> imghdr.what('8e5d7e9d873e2a9db0e31f9dfc11cf47')  # You can pass a file name or a file object as first param. See doc for optional 2nd param.
'png'

Python 2 imghdr doc

Python 3 imghdr doc

3
répondu Lewis Diamond 2014-10-08 15:04:05

avec la nouvelle bibliothèque de sous-processus, vous pouvez maintenant utiliser le code suivant (*solution nix only):

import subprocess
import shlex

filename = 'your_file'
cmd = shlex.split('file --mime-type {0}'.format(filename))
result = subprocess.check_output(cmd)
mime_type = result.split()[-1]
print mime_type
2
répondu berniey 2014-06-08 07:31:48