一)概论
MIME 类型(Multipurpose Internet Mail Extensions,简称为 MIME)最初是为电子邮件附件设计的,用于标识文件的内容类型。如今,MIME 类型在许多领域得到了广泛应用,例如浏览器、HTTP 传输和文件系统,帮助系统和应用程序理解如何处理特定文件。
MIME 类型是 Web 技术中的一个重要话题。
在本教程中,我们将讨论什么是 MIME 类型,并学习如何使用 Linux 命令行工具获取文件的 MIME 类型。
二)什么是 MIME 类型?
MIME 类型是一种标准,用于描述文件的性质和格式。MIME 类型构成了在互联网上分类文件类型的标准方式。首先,让我们看一个常见的 MIME 类型作为示例:
text/html
每个 MIME 类型由两部分组成:主类型和子类型,两者通过斜杠(/
)分隔。例如:在这个示例中,类型是“text”,而子类型是“html”。
目前,有十种注册类型:application(应用程序)、audio(音频)、example(示例)、font(字体)、image(图像)、message(消息)、model(模型)、multipart(多部分)、text(文本)和 video(视频)。
multipart/form-data text/xml text/csv text/plain application/xml application/zip application/pdf
在 MIME 类型中,类型和子类型不区分大小写。
子类型通常由一种媒体格式组成,例如上述示例中的“xml”或“pdf”。然而,它也可以包含其他内容,如树前缀或后缀,这取决于注册树中的不同规则。
text/html
表示 HTML 文本文件image/jpeg
表示 JPEG 图像文件application/json
表示 JSON 数据文件
MIME 类型让程序能够识别文件的类型并决定如何显示或处理它。
完整的 MIME 类型格式如下所示:
type "/" [tree "."] subtype ["+" suffix]
例如,当浏览器接收到一个 text/html
的 MIME 类型时,它知道该文件是网页,可以将其呈现给用户。
让我们再看一个 MIME 类型的示例:
application/vnd.api+json
这是一个特定于 API 的 MIME 类型,它指的是 JSON API。
在这个示例中,类型是“application”,子类型是“api”。“vnd.” 是供应商前缀,而 “+json” 是后缀,表明它可以被解析为 JSON 格式。
二)确定文件的 MIME 类型
MIME 类型提供了一种标准化的命名方式。然而,文件的 MIME 类型并不会存储在 Linux 文件系统中。确定文件 MIME 类型有两种方法:
- 查看文件扩展名
- 查看文件内容
接下来,让我们看看确定文件 MIME 类型的两种方法。
3.1. 根据文件扩展名
MIME 类型有时可以通过文件扩展名来确定,但并非总是如此。
如果文件没有扩展名或扩展名不正确,我们无法通过文件扩展名来确定 MIME 类型。
例如,我们可以将 JPG 图像文件重命名为 ZIP 文件扩展名。
3.2. 根据文件内容
另一种获取文件 MIME 类型的方法是通过读取其内容。
我们可以根据文件内容的特定特征来确定 MIME 类型。
例如,JPG 文件以十六进制签名 FF D8
开始,并以 FF D9
结束。
由于额外的 I/O 操作,这种方法比通过文件扩展名的方式要慢。然而,它可能更可靠。
3.3. 结合两种方法
在实际应用中,程序通常结合这两种方法来确定文件的 MIME 类型。例如,freedesktop.org 的 shared-mime-info 维护了一个 MIME 类型数据库,并允许其他程序(如 GNOME、KDE 和 Xfce)使用此数据库通过文件扩展名或内容查找相应的 MIME 类型。
让我们看一个在 shared-mime-info 中定义的 MIME 类型 “image/png” 的示例:
<?xml version="1.0" encoding="UTF-8"?> <mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> <mime-type type="image/png"> <comment xml:lang="en">PNG image</comment> <comment xml:lang="af">png beeld</comment> ... <magic priority="50"> <match type="string" value="\x89PNG" offset="0"/> </magic> <glob pattern="*.png"/> </mime-type> </mime-info>
在上述“image/png”示例中,<magic>
标签定义了通过文件内容识别 PNG 文件的规则。然而,<glob>
标签定义了通过文件扩展名来确定 MIME 类型的规则。
四) Linux 命令行工具
现在,让我们看看如何使用 Linux 命令行工具获取文件的 MIME 类型。在本节中,我们将介绍两个工具:file
命令和 xdg-mime
命令。
4.1. xdg-mime
命令
xdg-mime
命令是来自 freedesktop.org 的 xdg-utils
包的一个成员。这个包几乎在所有带有桌面环境的 Linux 发行版中都预装了。
xdg-mime
命令使用 shared-mime-info 数据库来确定 MIME 类型。它首先会尝试通过文件扩展名来识别 MIME 类型。如果失败,它将查看文件的内容。
使用 xdg-mime
命令获取文件 MIME 类型的语法是:
xdg-mime query filetype INPUT_FILE
让我们准备一个 JPG 图像文件(onePicture.jpg),看看 xdg-mime
命令是否可以获取 MIME 类型:
$ xdg-mime query filetype onePicture.jpg image/jpeg
接下来,我们来做一个小实验。让我们改变文件的扩展名,看看 xdg-mime
命令会给我们什么结果:
mv onePicture.jpg onePicture.zip xdg-mime query filetype onePicture.zip application/zip
糟糕!xdg-mime
命令给出了一个错误的 MIME 类型。这是因为 xdg-mime
命令首先尝试在数据库中通过文件扩展名查找 MIME 类型。
现在,让我们完全去掉文件扩展名,看看会发生什么:
mv onePicture.zip onePicture xdg-mime query filetype onePicture image/jpeg
我们再次得到了正确的结果。这是因为如果 xdg-mime
命令无法通过文件扩展名找到 MIME 类型,它将尝试通过文件内容查找 MIME 类型。
4.2. file
命令
大多数自由操作系统,如 FreeBSD 和 Linux,默认都附带 file
命令。我们将使用带有 –mime-type
选项的命令来获取文件的 MIME 类型。
让我们看看 file
命令是否可以获取相同 JPG 文件的 MIME 类型:
file --mime-type onePicture.jpg onePicture.jpg: image/jpeg
现在,让我们对文件扩展名做同样的更改,看看 file
命令是否仍然能报告正确的结果:
mv onePicture.jpg onePicture.zip file --mime-type onePicture.zip onePicture.zip: image/jpeg
太棒了!即使我们通过更改文件扩展名来尝试欺骗 file
命令,它仍然能够识别出正确的 MIME 类型。这是因为 file
命令并不依赖文件扩展名来确定文件的 MIME 类型,而是查看实际的文件内容。因此,在这种情况下,它更加可靠。
最后,我们删除文件扩展名,希望 file
命令仍然可以正常工作:
mv onePicture.zip onePicture file --mime-type onePicture onePicture: image/jpeg
正如我们所预期的那样,它再次给出了正确的结果。
五)为什么 MIME 类型很重要?
MIME 类型的重要性体现在多个方面:
- 浏览器和网络传输:当服务器通过 HTTP 发送文件时,它会在响应头中包含 MIME 类型。浏览器使用这个信息来决定如何处理内容。例如,若 MIME 类型是
text/html
,浏览器会将其作为网页呈现;若是application/pdf
,则通常会启动 PDF 阅读器插件。 - 安全性:正确设置 MIME 类型有助于防止安全问题。例如,若服务器错误地将一个可执行文件标记为
text/plain
,浏览器可能会将其视为普通文本文件,忽略潜在的安全威胁。 - 文件关联:操作系统和应用程序使用 MIME 类型来关联文件与特定的软件。例如,
image/png
文件通常会与图像查看器程序关联打开。 - 数据传输和存储:在传输和存储数据时,MIME 类型提供了标准化的方式来描述数据格式,使得不同系统或应用可以正确解读和处理数据。
六) 结论
在本文中,我们讨论了什么是 MIME 类型以及 MIME 类型是如何命名的。然后,我们探讨了在 Linux 中确定文件 MIME 类型的常用方法。
最后,我们学习了两种获取文件 MIME 类型的 Linux 命令:file
和 xdg-mime
命令。通过一些示例,我们讨论了为什么这两个命令在相同的文件上可能会表现不同。