Как проверить тип файлов без расширений в 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, но на самом деле миметипы победили » t здесь работает, потому что он основан на расширениях файлов. Им нужна 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 - это первое совпадение для image / 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
@ Ричард. Не могли бы вы подробнее остановиться на накладных расходах? Что делает библиотеку 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 - это способ. Вы можете получить вывод команды описанным выше способом, как это сообщение сказал

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) insteed. - person emnoor; 06.06.2014
comment
Почему бы просто не запустить subprocess.check_output(['file', '--mime-type', filename]) вместо использования shlex.split? - person Flimm; 03.08.2016

также вы можете использовать этот код (чистый питон на 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) = ›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, но с помощью модуля python "sh" вы можете просто вызвать любую команду оболочки.

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

pip install sh

импорт ш

sh.file ("/ корень / файл")

Вывод: / root / file: текст ASCII

person Lelouch    schedule 02.02.2019