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

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

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

Как это сделать?

Ответ 1

Существуют библиотеки Python, которые могут распознавать файлы на основе их содержимого (обычно это заголовок/магическое число) и которые не зависят от имени файла или расширения.

Если вы обращаетесь к множеству разных типов файлов, вы можете использовать python-magic. Это просто связка Python для хорошо установленной библиотеки magic. У этого есть хорошая репутация и (небольшое одобрение) в ограниченном использовании, которое я сделал из него, он был солидным.

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

Ответ 2

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

Ответ 3

В unix и linux есть команда file, чтобы угадать типы файлов. Там даже порт Windows.

На странице man:

Файл проверяет каждый аргумент, пытаясь его классифицировать. Есть три наборов тестов, выполненных в этом порядке: тесты файловой системы, магическое число тесты и языковые тесты. Первый тест, который преуспевает, вызывает тип файла для печати. ​​

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

изменить: Игнорировать мой ответ. Вместо этого используйте Chris Johnson .

Ответ 4

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

Как указал Стивен, subprocess - путь. Вы можете получить вывод команды следующим образом: post сказал

Ответ 5

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

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

Ответ 6

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

Ответ 7

С более новой библиотекой подпроцессов теперь вы можете использовать следующий код (только решение 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

Ответ 8

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

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

pip install sh

импорт ш

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

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

Ответ 9

также вы можете использовать этот код (чистый питон на 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"

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