Как да проверя тип файлове без разширения в python?

Имам папка пълна с файлове и те нямат разширение. Как мога да проверя типове файлове? Искам да проверя типа на файла и съответно да променя името на файла. Да приемем, че функция filetype(x) връща тип файл като png. Искам да направя това:

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

Как да направя това?


person emnoor    schedule 07.06.2012    source източник
comment
rel: stackoverflow.com/questions/43580/   -  person georg    schedule 07.06.2012
comment
Ще трябва да сте по-конкретни по отношение на file types. Имате предвид да определите дали е gif, png, bmp или jpg? Искате ли просто да знаете дали е текстово/двоично? изпълним?   -  person JoeFish    schedule 07.06.2012
comment
@thg435, след като имате типа MIME, има ли начин да го конвертирате в подходящо разширение на името на файла?   -  person Mark Ransom    schedule 07.06.2012
comment
@Mark: да, използвай guess_extension, но всъщност mimetypes няма не работи тук, защото е базиран на файлови разширения. Това, от което се нуждаят, е libmagic (вижте втория отговор на връзката).   -  person georg    schedule 07.06.2012
comment
@thg435, не е много стабилно - application/jpeg връща .jpe вместо предпочитаното .jpg. Наистина изглежда като отгатване.   -  person Mark Ransom    schedule 07.06.2012
comment
@Mark: не, не предполага, взема информация направо от локалната база данни на mime (/etc/mime.types или каквото и да е). jpe случайно е първото съвпадение за изображение/jpeg, опитайте guess_all_extensions, за да ги видите всички.   -  person georg    schedule 07.06.2012
comment
@JoeFish определя дали е gif, png, pdf или jpg или нещо друго   -  person emnoor    schedule 07.06.2012
comment
опитайте това pypi.org/project/filetype?   -  person zx1986    schedule 18.01.2019


Отговори (9)


Има библиотеки на Python, които могат да разпознават файлове въз основа на тяхното съдържание (обикновено заглавка / магическо число) и които не разчитат на името или разширението на файла.

Ако адресирате много различни типове файлове, можете да използвате python-magic. Това е просто обвързване на Python за добре установената magic библиотека. Това има добра репутация и (малко одобрение) при ограниченото използване, което съм го използвал, беше солидно.

Има и библиотеки за по-специализирани типове файлове. Например стандартната библиотека на Python има модула imghdr, който прави същото само за изображение типове файлове.

Ако имате нужда от проверка на типове файлове без зависимости (чист Python), вижте filetype.

person Chris Johnson    schedule 07.06.2012
comment
Пакетът python-magic-win64 работи за мен в Windows - person ChesuCR; 25.01.2019
comment
imghdr с комбинация от filetype работи за мен в windows - person Hrushikesh Dhumal; 23.10.2019

Библиотеката Python Magic осигурява функционалността, от която се нуждаете.

Можете да инсталирате библиотеката с pip install python-magic и да я използвате, както следва:

>>> 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'

Кодът на Python в този случай извиква libmagic под капака, което е същата библиотека използвани от командата *NIX file. По този начин това прави същото нещо като отговорите, базирани на подпроцес/обвивка, но без това допълнително натоварване.

person Richard    schedule 26.06.2014
comment
Имайте предвид, че пакетът debian/ubuntu, наречен python-magic, е различен от пакета pip със същото име. И двете са import magic, но имат несъвместимо съдържание. Вижте stackoverflow.com/a/16203777/3189 за повече. - person Hamish Downer; 28.04.2015
comment
@Richard Имате ли нещо против да уточните режийния аспект? Какво прави библиотеката python-magic по-ефективна от използването на подпроцесни подходи? - person Greg; 29.03.2017
comment
Страхотен отговор. Ако видите failed to find libmagic. Check your installation, стартирайте brew install libmagic и опитайте отново - person stevec; 07.02.2021

В unix и linux има команда file за отгатване на типове файлове . Има дори порт за Windows.

От страницата на ръководството:

Файл тества всеки аргумент в опит да го класифицира. Има три комплекта тестове, изпълнявани в този ред: тестове на файловата система, тестове с магически числа и езикови тестове. Първият успешен тест води до отпечатване на типа на файла.

Ще трябва да изпълните командата file с модула subprocess и след това да анализирате резултатите, за да разберете разширение.

редактиране: Игнорирайте отговора ми. Вместо това използвайте отговора на Крис Джонсън.

person Steven Rumbalski    schedule 07.06.2012
comment
+1 Не знаех, че file е направил толкова много. # file arc.gif arc.gif: GIF image data, version 89a, 234 x 269 - person JoeFish; 07.06.2012
comment
Е, надявах се някой да има по-добър отговор. Все още има много работа за OP, това не е просто извикване на функция. - person Steven Rumbalski; 07.06.2012
comment
+1 Едно предимство при използването на командата file е, че тя е естествена за (повечето?) Linux дистрибуции, докато python-magic не е и трябва да бъде изтеглена и инсталирана, преди да може да се използва. Това е донякъде проблем, ако скриптът, използващ модула, трябва да бъде преносим. - person HelloGoodbye; 22.01.2014

В случай на изображения можете да използвате модула 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

person Lewis Diamond    schedule 07.10.2014

Можете също така да инсталирате официалното file свързване за Python, библиотека, наречена file-magic (тя не използва ctypes, като python-magic).

Предлага се в PyPI като file-magic и в Debian като python-magic. За мен тази библиотека е най-добрата за използване, тъй като е достъпна на PyPI и на Debian (и вероятно други дистрибуции), което прави процеса на внедряване на вашия софтуер по-лесен. Аз съм блог за това как да използвайте го също.

person Álvaro Justen    schedule 05.08.2016

import subprocess
p = sub.Popen('file yourfile.txt', stdout=sub.PIPE, stderr=sub.PIPE)
output, errors = p.communicate()
print(output)

Както Стивън посочи, subprocess е начинът. Можете да получите изхода на командата по пътя по-горе като този post каза

person xvatar    schedule 07.06.2012
comment
И как улавяте изхода? - person Mark Ransom; 07.06.2012
comment
@MarkRansom съжалявам, че не беше добър начин, моля, вижте моите актуализации по-горе - person xvatar; 07.06.2012
comment
Ако трябва да взаимодействате с вашата система, вместо да използвате библиотека на Python, решението е неоптимално през повечето време, защото вероятно не е полезно в други операционни системи с различен API. - person erikbwork; 17.12.2013

С по-нова библиотека с подпроцеси вече можете да използвате следния код (*nix само решение):

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
person berniey    schedule 06.06.2014
comment
Благодаря за отговора. Между другото, не трябва да използвате str.split() на cmd ред. вместо това използвайте shlex.split(cmd). - person emnoor; 06.06.2014
comment
Вместо да използвате shlex.split, защо просто не стартирате subprocess.check_output(['file', '--mime-type', filename])? - person Flimm; 03.08.2016

също можете да използвате този код (чист python с 3 байта от заглавния файл):

full_path = os.path.join(MEDIA_ROOT, pathfile)

try:
    image_data = open(full_path, "rb").read()
except IOError:
    return "Incorrect Request :( !!!"

header_byte = image_data[0:3].encode("hex").lower()

if header_byte == '474946':
    return "image/gif"
elif header_byte == '89504e':
    return "image/png"
elif header_byte == 'ffd8ff':
    return "image/jpeg"
else:
    return "binary file"

без никаква инсталация на пакет [и актуализирана версия]

person evergreen    schedule 06.07.2019
comment
Как мога да проверя за xlsx? - person Harsha Biyani; 14.05.2020
comment
Можете да използвате 4 или 8 байта. XLSX(MS Office Open XML Format Document) =› 50 4B 03 04 (4 байта) =› ASCII (PK••) или XLSX(MS Office 2007 документи) = › 50 4B 03 04 14 00 06 00 (8 байта) =› ASCII (PK•••••••) - person evergreen; 14.05.2020

Работи само за Linux, но с помощта на модула "sh" python можете просто да извикате всяка команда на обвивката

https://pypi.org/project/sh/

pip инсталирайте sh

внос ш

sh.file("/root/file")

Изход: /корен/файл: ASCII текст

person Lelouch    schedule 02.02.2019