Як перевірити тип файлів без розширень у python?


87

У мене папка, заповнена файлами, і вони не мають розширення. Як я можу перевірити типи файлів? Я хочу перевірити тип файлу та відповідно змінити ім'я файлу. Припустимо, функція filetype(x)повертає тип файлу типу png. Я хочу зробити це:

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

Як це зробити?



Вам доведеться бути більш конкретним щодо file types. Ви маєте на увазі визначення, чи це gif, png, bmp чи jpg? Ви просто хочете знати, це текстовий / двійковий файл? Виконання?
JoeFish

@ thg435, як тільки у вас є тип MIME, чи є спосіб перетворити його на відповідне розширення імені файлу?
Марк Ренсом

@Mark: так, використовуйте здогадка_розширення , але насправді, mimeypes тут не працюватимуть, оскільки вона базується на розширеннях файлів. Що їм потрібно, це libmagic (див. Другу відповідь за посиланням).
georg

1
спробувати цей pypi.org/project/filetype ?
zx1986

Відповіді:


89

Є бібліотеки Python, які можуть розпізнавати файли на основі їх вмісту (зазвичай це заголовок / магічне число) і які не покладаються на ім'я файлу або розширення.

Якщо ви звертаєтесь до багатьох типів файлів, ви можете використовувати python-magic. Це просто прив’язка Python для добре налагодженої magicбібліотеки. Це має хорошу репутацію та (невелика підтримка), в обмеженому використанні, яке я ним використав, воно було твердим.

Існують також бібліотеки для більш спеціалізованих типів файлів. Наприклад, у стандартній бібліотеці Python є imghdrмодуль, який робить те саме для типів файлів зображень.

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


2
Пакет python-magic-win64працював у мене в Windows
ChesuCR

2
imghdr з комбінацією типів файлів працювали для мене в вікнах
Hrushikesh Dhumal

61

Бібліотека 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. Таким чином, це робить те саме, що відповіді на основі підпроцесу / оболонки, але без цих накладних витрат.


6
Пам'ятайте, що пакет debian / ubuntu під назвою python-magic відрізняється від однойменного пакета pip. Обидва вони import magicмають несумісний вміст. Докладніше див. Na stackoverflow.com/a/16203777/3189 .
Hamish Downer,

1
@Richard Чи не заперечуєте ви над детальним описом? Що робить python-magicбібліотеку більш ефективною, ніж використання підпроцесорних підходів?
Грег

9

У unix та linux існує fileкоманда вгадувати типи файлів. Існує навіть порт для Windows .

Зі сторінки користувача :

Файл перевіряє кожен аргумент, намагаючись класифікувати його. Існує три набори тестів, що виконуються в такому порядку: тести файлової системи, тести магічного числа та мовні тести. Перший успішний тест викликає друк типу файлу.

Вам потрібно буде запустити fileкоманду з subprocessмодулем, а потім проаналізувати результати, щоб з’ясувати розширення.

редагувати: ігнорувати мою відповідь. Використовуйте Кріса Джонсона відповідь замість цього.


+1 Я не підозрював file, що зробив так багато. # file arc.gif arc.gif: GIF image data, version 89a, 234 x 269
JoeFish

Ну, я сподівався, що хтось має кращу відповідь. Для ОП ще багато роботи, це не простий виклик функції.
Steven Rumbalski

2
+1 Однією перевагою використання fileкоманди є те, що вона є рідною для (більшості?) Дистрибутивів Linux, тоді як python-magicце не так, і її потрібно завантажити та встановити перед тим, як її можна використовувати. Це певна проблема, якщо сценарій, що використовує модуль, повинен бути портативним.
HelloGoodbye


6

Ви також можете встановити офіційне fileприв'язування для Python, бібліотеки під назвою file-magic(вона не використовує ctypes, наприклад python-magic).

Він доступний на PyPI як файлова магія, а на Debian як python-магія . Для мене ця бібліотека найкраща у використанні, оскільки вона доступна на PyPI та Debian (і, мабуть, інших дистрибутивах), що полегшує процес розгортання вашого програмного забезпечення. Я також писав у блозі про те, як ним користуватися .


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

Як зазначив Стівен, subprocessце шлях. Ви можете отримати вихід команди способом вище, як сказано в цій публікації


І як ви фіксуєте результат?
Марк Ренсом

@MarkRansom вибачте, що це був невдалий спосіб, перегляньте мої оновлення вище
xvatar

Якщо вам потрібно взаємодіяти з вашою системою замість того, щоб використовувати бібліотеку Python, рішення більшість часу є неоптимальним, оскільки воно, ймовірно, не корисно в інших операційних системах з іншим API.
erikbwork

4

З новою бібліотекою підпроцесу тепер ви можете використовувати такий код (рішення лише для * 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

Дякую за відповідь. До речі, ви не повинні використовувати str.split () на лінії cmd. використовуйте shlex.split (cmd) з підкладкою
emnoor

Замість використання shlex.split, чому б просто не запустити subprocess.check_output(['file', '--mime-type', filename])?
Флімм

1

також ви можете використовувати цей код (чистий 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"

без встановлення пакету [та оновлення версії]


Як я можу перевірити xlsx?
Харша Біяні

Ви можете використовувати 4 або 8 байт. XLSX (документ у форматі MS Office Open XML) => 50 4B 03 04 (4 байти) => ASCII (PK ••) або XLSX (документи MS Office 2007) => 50 4B 03 04 14 00 06 00 (8 байтів) = > ASCII (PK ••••••)
вічнозелений

0

Працює лише для Linux, але за допомогою модуля py sh python ви можете просто викликати будь-яку команду оболонки

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

pip встановити sh

імпорт ш

sh.file ("/ root / файл")

Вихідні дані: / root / файл: текст ASCII

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.