golang高性能MIME类型嗅探与检测插件库mimemagic的使用
Golang高性能MIME类型嗅探与检测插件库mimemagic的使用
简介
mimemagic是一个强大且多功能的MIME嗅探包,它使用预编译的全局模式、魔术数字签名、XML文档命名空间和挂载卷的树魔术,这些数据都来自XDG shared-mime-info数据库。
功能特性
- 纯Go实现,无外部依赖/C库绑定
- 支持1003种MIME类型,包含描述、缩写(如可用)、常用别名、扩展名、图标和子类
- 493个魔术签名测试(包含1147个独立模式),支持范围搜索和位掩码
- 1099个全局模式,用于基于文件名的匹配
- 11个树魔术签名和28个XML命名空间/本地名称对
- 包含用于生成自定义MIME定义的XML文件解析器
- 提供基于此库的全功能CLI工具,性能优异
- 跨平台支持
安装
安装库:
go get github.com/zRedShift/mimemagic/v2
安装CLI工具:
go get github.com/zRedShift/mimemagic/v2/cmd/mimemagic
使用示例
库使用示例
package main
import (
"fmt"
"github.com/zRedShift/mimemagic/v2"
"strings"
)
func main() {
// 忽略可能出现的读取错误
mimeType, _ := mimemagic.MatchFilePath("sample.svgz", -1)
// 输出: image/svg+xml-compressed
fmt.Println(mimeType.MediaType())
// 输出: compressed SVG image
fmt.Println(mimeType.Comment)
// 输出: SVG (Scalable Vector Graphics)
fmt.Printf("%s (%s)\n", mimeType.Acronym, mimeType.ExpandedAcronym)
// 输出: application/gzip
fmt.Println(strings.Join(mimeType.SubClassOf, ", "))
// 输出: .svgz
fmt.Println(strings.Join(mimeType.Extensions, ", "))
// 判断文件类型
switch mimeType.Media {
case "image":
fmt.Println("This is an image.")
case "video":
fmt.Println("This is a video file.")
case "audio":
fmt.Println("This is an audio file.")
case "application":
fmt.Println("This is an application.")
default:
fmt.Printf("This is a(n) %s.", mimeType.Media)
}
// 检查是否是特定扩展名: true
fmt.Println(mimeType.IsExtension(".svgz"))
}
CLI工具使用
CLI工具的基本用法:
Usage: mimemagic [options] <file> ...
确定给定文件的MIME类型。
选项:
-c 仅使用文件内容确定MIME类型
-f 仅使用文件名确定MIME类型(不检查文件是否存在)
-i 以人类可读格式输出MIME类型
-l int
从文件开头检查的字节数。设为负值则读取整个文件
-t 使用树魔术确定目录/挂载卷的MIME类型
-x 使用XML文件中的本地名称和命名空间确定MIME类型
参数:
file
要测试的文件。使用'-'从标准输入读取
示例:
$ mimemagic -c sample.svgz
application/gzip
$ mimemagic *.svg*
Olympic_rings_with_transparent_rims.svg: image/svg+xml
Piano.svg.png: image/png
RAID_5.svg: image/svg+xml
sample.svgz: image/svg+xml-compressed
$ cat /dev/urandom | mimemagic -
application/octet-stream
$ ls software; mimemagic -i -t software/
autorun
UNIX software
性能
Match()函数在400多个完全不同文件(每个代表一个独特的MIME类型)上的平均性能为13 ± 7 μs/op。MatchGlob()平均为900 ± 200 ns/op,MatchMagic()平均为12 ± 7 μs/op。
许可证
生成的代码(magicsigs.go、globs.go、treemagicsigs.go、namespaces.go和mediatypes.go)是shared-mime-info的衍生作品,因此遵循GPL-2.0-or-later许可证。
更多关于golang高性能MIME类型嗅探与检测插件库mimemagic的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang高性能MIME类型嗅探与检测插件库mimemagic的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang高性能MIME类型嗅探库mimemagic使用指南
mimemagic简介
mimemagic是一个高性能的MIME类型检测库,它通过分析文件内容而非扩展名来确定文件的真实MIME类型。相比标准库的http.DetectContentType
,mimemagic提供了更精确的检测能力。
安装
go get github.com/zRedShift/mimemagic
基本使用
快速检测
package main
import (
"fmt"
"github.com/zRedShift/mimemagic"
"os"
)
func main() {
file, err := os.Open("example.pdf")
if err != nil {
panic(err)
}
defer file.Close()
// 快速检测MIME类型
mimeType := mimemagic.Match("", file)
fmt.Println("Detected MIME type:", mimeType)
}
高级配置
func advancedDetection() {
file, _ := os.Open("example.jpg")
defer file.Close()
// 创建自定义匹配器
matcher := mimemagic.NewMatcher(
mimemagic.IgnoreExtension(), // 忽略文件扩展名
mimemagic.Limit(1024), // 只读取前1024字节
)
mimeType := matcher.Match("", file)
fmt.Println("Detected MIME type:", mimeType)
}
性能优化技巧
- 复用matcher对象:避免重复创建matcher
var globalMatcher = mimemagic.NewMatcher()
func detectMIME(filePath string) string {
file, _ := os.Open(filePath)
defer file.Close()
return globalMatcher.Match("", file)
}
- 限制读取范围:对于大文件,限制读取范围提高性能
matcher := mimemagic.NewMatcher(
mimemagic.Limit(4096), // 只读取前4KB
)
- 预加载常用类型:减少首次检测延迟
func init() {
// 预加载常用MIME类型
mimemagic.Load("image/jpeg", "application/pdf", "text/plain")
}
实际应用示例
Web文件上传检测
func uploadHandler(w http.ResponseWriter, r *http.Request) {
file, header, err := r.FormFile("file")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
// 检测MIME类型
mimeType := mimemagic.Match(header.Filename, file)
// 验证允许的类型
allowed := map[string]bool{
"image/jpeg": true,
"image/png": true,
"image/gif": true,
}
if !allowed[mimeType] {
http.Error(w, "Unsupported file type", http.StatusUnsupportedMediaType)
return
}
// 处理文件...
fmt.Fprintf(w, "Uploaded %s (%s)", header.Filename, mimeType)
}
批量文件检测
func batchDetect(files []string) map[string]string {
results := make(map[string]string)
matcher := mimemagic.NewMatcher()
for _, filePath := range files {
file, err := os.Open(filePath)
if err != nil {
continue
}
mimeType := matcher.Match(filePath, file)
results[filePath] = mimeType
file.Close()
}
return results
}
与标准库对比
func compareDetection() {
file, _ := os.Open("example.docx")
defer file.Close()
// 标准库检测
buf := make([]byte, 512)
_, _ = file.Read(buf)
stdMime := http.DetectContentType(buf)
// mimemagic检测
_, _ = file.Seek(0, 0)
mmMime := mimemagic.Match("", file)
fmt.Printf("Standard lib: %s\nmimemagic: %s\n", stdMime, mmMime)
}
注意事项
- mimemagic可能需要读取文件开头部分内容,确保文件可读
- 对于某些特殊文件类型,可能需要调整检测参数
- 检测结果可能受文件内容影响,不完全可靠
- 考虑结合文件扩展名进行双重验证
mimemagic提供了比标准库更精确的MIME类型检测能力,特别适合需要精确识别文件类型的应用场景,如文件上传验证、内容管理系统等。