如何检查不带扩展名的文件类型? [重复]

问题描述 投票:0回答:10

我有一个装满文件的文件夹,但它们没有扩展名。如何检查文件类型?我想检查文件类型并相应地更改文件名。我们假设函数

filetype(x)
返回类似
png
的文件类型。我想做这个:

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

我该怎么做?

python filesystems identification
10个回答
123
投票

有些 Python 库可以根据文件内容(通常是标头/幻数)来识别文件,并且不依赖于文件名或扩展名。

如果您要处理多种不同的文件类型,则可以使用

python-magic
。这只是完善的
magic
库的 Python 绑定。这具有良好的声誉,并且(小认可)在我对它的有限使用中,它一直很可靠。

原生 imghdr 库可能很有用,但自 Python 3.11 起已弃用,并将在 Python 3.13 中删除。

如果您需要无依赖(纯Python)文件类型检查,请参阅

filetype


76
投票

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
命令使用的库相同。因此,这与基于子进程/shell 的答案执行相同的操作,但没有开销。


11
投票

在unix和linux上有

file
命令来猜测文件类型。甚至还有一个 windows 端口

来自手册页

File 测试每个参数以尝试对其进行分类。有三种 按此顺序执行的测试集:文件系统测试、幻数 测试、语言测试。成功的第一个测试会导致 要打印的文件类型。

您需要使用

file
模块运行
subprocess
命令,然后解析结果以找出扩展名。

编辑:忽略我的回答。请改用 Chris Johnson 的 answer


10
投票

对于图像,您可以使用

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 文档
Python 3 imghdr 文档


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

正如史蒂文指出的那样,

subprocess
就是出路。你可以通过上面的方式获取命令输出,就像这个post所说的那样


6
投票

您还可以安装 Python 的官方

file
绑定,这是一个名为
file-magic
的库(它不使用 ctypes,如
python-magic
)。

它在 PyPI 上作为 file-magic 提供,在 Debian 上作为 python-magic 提供。对我来说,这个库是最好用的,因为它可以在 PyPI 和 Debian(可能还有其他发行版)上使用,从而使部署软件的过程变得更容易。 我还在博客中介绍了如何使用它


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

3
投票

您也可以使用此代码(纯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"

无需安装任何软件包[和更新版本]


0
投票

仅适用于 Linux,但使用“sh”python 模块,您可以简单地调用任何 shell 命令

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

pip安装sh

导入sh

sh.file("/root/file")

输出: /root/file: ASCII 文本


0
投票

此代码递归列出给定文件夹中给定扩展名的所有文件

import magic
import glob
from os.path import isfile

ROOT_DIR = 'backup'
WANTED_EXTENSION = 'sqlite'

for filename in glob.iglob(ROOT_DIR + '/**', recursive=True):
    if isfile(filename):
        extension = magic.from_file(filename, mime = True)
        if WANTED_EXTENSION in extension:
            print(filename)

https://gist.github.com/izmcm/6a5d6fa8d4ec65fd9851a1c06c8946ac

© www.soinside.com 2019 - 2024. All rights reserved.