python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python判断文件格式

使用Python判断一个文件格式的多种实现方案

作者:诸神缄默不语

本文将以图片文件为例,为大家系统介绍一下五种用Python判断文件真实格式的方法,并分析它们的优缺点,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

在日常开发中,我们经常需要判断一个文件的真实格式,尤其是在处理用户上传、文件解析或数据清洗的场景。仅仅依赖文件扩展名往往不够可靠,因为用户可以随意修改后缀名。本文将以图片文件为例,介绍几种用Python判断文件格式的常见方法,分析它们的优缺点,并提供完整的代码实例。

为什么不能只相信扩展名

在Windows或Linux系统中,文件扩展名只是文件名的一部分,操作系统并不强制要求其与内容匹配。例如,将一个文本文件重命名为 image.jpg,它依然是一个文本文件。如果程序仅根据.jpg来解析,就会出错。因此,从文件内容判断格式才是根本

下面我们由浅入深,介绍几种方案。

方法一:基于文件扩展名(最基础,最不可靠)

直接使用os.path.splitext获取文件后缀,然后映射到格式。

代码示例

import os

def guess_format_by_extension(file_path):
    ext = os.path.splitext(file_path)[1].lower()
    ext_to_format = {
        '.jpg': 'JPEG',
        '.jpeg': 'JPEG',
        '.png': 'PNG',
        '.gif': 'GIF',
        '.bmp': 'BMP',
        '.webp': 'WebP',
    }
    return ext_to_format.get(ext, 'Unknown')

print(guess_format_by_extension(file_path))

输出: JPEG

优点

缺点

方法二:使用mimetypes模块(同样基于扩展名)

Python标准库的mimetypes模块可以根据扩展名猜测MIME类型,但本质还是依赖扩展名。

代码示例

import mimetypes

mime_type, _ = mimetypes.guess_type(file_path)

print(mime_type)

输出:image/jpeg

优点

缺点

方法三:使用python-magic(读取文件内容,准确度高)

python-magiclibmagic库的Python绑定,它能根据文件内容识别MIME类型,是Linux file命令的底层实现。这是最可靠的方案之一

安装

Linux和MacOS系统应该可以直接安装:

pip install python-magic

Windows系统上缺少libmagic的DLL,有两种解决方案,一是直接安装python-magic-bin,包含了所需DLL:

pip install python-magic-bin

另一种解决方案是安装libmagic的DLL,谷歌搜索建议用vcpkg安装,我没试过:

vcpkg install libmagic

代码示例

import magic

def guess_format_with_magic(file_path):
    with open(file_path, 'rb') as f:
        file_data = f.read(2048)
    mime_type = magic.from_buffer(file_data, mime=True)
    return mime_type

print(guess_format_with_magic(file_path))

输出:image/jpeg

这里只读了前2048个字节是因为够识别文件格式了。如果文件较大,可以适当增加读取的字节数(如 8192),但 2048 对常见图片、文档等已经足够。

这里是先读取文件内容为流,然后再调用python-magic。另外还有一个接口是magic.from_file(filename, mime=True),如果直接传入字符串格式的文件路径,文件路径带中文时会报错。当路径是纯英文时就可以用:

import magic

print(magic.from_file("p1.jpg", mime=True))

输出也是:image/jpeg

优点

缺点

方法四:手动检查文件头(魔数,Magic Number)

每种文件格式通常在文件开头有特定的标识字节(魔数)。例如:

我们可以读取文件前几个字节,与已知魔数对比。

代码示例

def check_image_format(file_path):
    with open(file_path, 'rb') as f:
        header = f.read(12)  # 读取前12字节通常足够判断常见图片格式

    if header.startswith(b'\xff\xd8\xff'):
        return 'JPEG'
    elif header.startswith(b'\x89PNG\r\n\x1a\n'):
        return 'PNG'
    elif header.startswith(b'GIF87a') or header.startswith(b'GIF89a'):
        return 'GIF'
    elif header.startswith(b'BM'):
        return 'BMP'
    elif header.startswith(b'RIFF') and header[8:12] == b'WEBP':
        # WebP 格式检查(简化版)
        return 'WebP'
    else:
        return 'Unknown'

print(check_image_format(file_path))

输出:JPEG

优点

缺点

方法五:针对图像:利用图像处理库(如Pillow)尝试打开

如果能用Pillow库成功打开文件并读取格式,说明它是一个可识别的图片。这种方法不仅能判断是不是图片,还能获取尺寸、模式等元信息。

安装

pip install Pillow

代码示例

from PIL import Image

def guess_format_with_pillow(file_path):
    try:
        with Image.open(file_path) as img:
            return img.format  # 返回 'JPEG', 'PNG' 等
    except Exception:
        return None  # 无法打开,不是图片或文件损坏

输出:JPEG

优点

缺点

方案对比总结

方法准确性速度依赖适用范围优点缺点
文件扩展名极低最快所有文件简单、快速极易被欺骗
mimetypes最快标准库所有文件返回MIME类型同扩展名,不读内容
python-magic较快python-magic所有文件准确、标准跨平台配置略麻烦
文件头魔数中高自定义格式纯Python,可控需维护魔数表,覆盖不全
Pillow尝试打开Pillow图片文件能验证完整性,获取元信息仅图片,非图片会抛异常

实践建议

结语

判断文件格式是文件处理的基础,Python提供了多种灵活的方式。从简单的扩展名到基于内容的魔数识别,再到成熟的第三方库,开发者可以根据项目的具体需求权衡准确性、性能和依赖。希望本文的梳理能帮助你选择合适的方案,写出更健壮的代码。

在实际应用中,建议将文件内容识别作为首要手段,并将扩展名作为一种辅助验证或默认提示。毕竟,真实的内容比名字更值得信任

到此这篇关于使用Python判断一个文件格式的多种实现方案的文章就介绍到这了,更多相关Python判断文件格式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文