golang基于魔法数字的MIME类型检测插件库mimetype的使用
Golang基于魔法数字的MIME类型检测插件库mimetype的使用
简介
mimetype是一个用于基于魔法数字检测MIME类型和文件扩展名的Golang包。它具有以下特点:
- Goroutine安全、可扩展、无C绑定
- 快速精确的MIME类型和文件扩展名检测
- 支持大量MIME类型
- 可以扩展其他文件格式
- 优先处理常见文件格式
- 区分文本和二进制文件
- 无外部依赖
安装
go get github.com/gabriel-vasile/mimetype
使用示例
package main
import (
"fmt"
"github.com/gabriel-vasile/mimetype"
"io"
"os"
)
func main() {
// 示例1: 从字节切片检测MIME类型
data := []byte("GIF87a")
mtype := mimetype.Detect(data)
fmt.Println(mtype.String(), mtype.Extension()) // 输出: image/gif .gif
// 示例2: 从Reader检测MIME类型
file, err := os.Open("example.pdf")
if err != nil {
panic(err)
}
defer file.Close()
mtype, err = mimetype.DetectReader(file)
if err != nil {
panic(err)
}
fmt.Println(mtype.String(), mtype.Extension()) // 输出: application/pdf .pdf
// 示例3: 从文件路径直接检测
mtype, err = mimetype.DetectFile("example.jpg")
if err != nil {
panic(err)
}
fmt.Println(mtype.String(), mtype.Extension()) // 输出: image/jpeg .jpg
}
高级用法
增加检测限制
对于某些文件格式(如Microsoft Office文档),它们的签名可能位于文件末尾。可以增加检测限制:
// 设置检测限制为1MB
mimetype.SetLimit(1024*1024)
// 或者不设限制,检测整个文件
mimetype.SetLimit(0)
mtype, err := mimetype.DetectFile("large_file.doc")
if err != nil {
panic(err)
}
fmt.Println(mtype.String())
扩展自定义MIME类型
// 定义一个新的MIME类型检测器
foobarDetector := func(raw []byte, limit uint32) bool {
return len(raw) > 4 && bytes.Equal(raw[:4], []byte("FOOB"))
}
// 创建MIME类型节点
foobarMIME := mimetype.NewNode("application/foobar", ".fb", foobarDetector)
// 将新类型添加到检测树中
mimetype.Extend(mimetype.Lookup("application/octet-stream"), foobarMIME)
// 测试新类型
data := []byte("FOOBAR")
mtype := mimetype.Detect(data)
fmt.Println(mtype.String()) // 输出: application/foobar
注意事项
- 像mimetype这样的库应作为最后手段使用
- 使用魔法数字检测内容类型速度慢、不准确且非标准
- 大多数协议都有指定此类元数据的方法(如HTTP和SMTP中的Content-Type头)
工作原理
mimetype使用分层结构来维护MIME类型检测逻辑。这减少了检测文件类型所需的调用次数。例如,Microsoft Office文件只是zip存档,包含特定的元数据文件。一旦文件被识别为zip,就不需要检查它是否是文本文件,但值得检查它是否是Microsoft Office文件。
为了防止将整个文件加载到内存中,当从reader或文件检测时,mimetype限制自己只读取输入的头部。
贡献
欢迎贡献。当提交新文件格式检测的PR时,请确保将记录添加到mimetype_test.go中的测试用例列表中。对于复杂文件,可以在testdata目录中添加记录。
更多关于golang基于魔法数字的MIME类型检测插件库mimetype的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang基于魔法数字的MIME类型检测插件库mimetype的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang基于魔法数字的MIME类型检测库mimetype使用指南
简介
mimetype
是一个基于魔法数字(Magic Numbers)检测文件MIME类型的Go语言库。它通过分析文件内容的特征字节序列(即魔法数字)来确定文件类型,这种方法比依赖文件扩展名更可靠。
安装
go get github.com/gabriel-vasile/mimetype
基本使用
1. 检测文件MIME类型
package main
import (
"fmt"
"github.com/gabriel-vasile/mimetype"
"os"
)
func main() {
// 打开文件
file, err := os.Open("example.pdf")
if err != nil {
panic(err)
}
defer file.Close()
// 检测MIME类型
mtype, err := mimetype.DetectReader(file)
if err != nil {
panic(err)
}
fmt.Println("MIME类型:", mtype.String()) // application/pdf
fmt.Println("扩展名:", mtype.Extension()) // .pdf
fmt.Println("是否是PDF:", mtype.Is("application/pdf")) // true
}
2. 直接检测字节切片
data := []byte{0x89, 0x50, 0x4E, 0x47} // PNG文件的开头字节
mtype := mimetype.Detect(data)
fmt.Println(mtype) // image/png
高级功能
1. 自定义检测器
package main
import (
"fmt"
"github.com/gabriel-vasile/mimetype"
)
func main() {
// 创建一个新的MIME检测器
customMIME := mimetype.New("application/x-custom", ".custom",
func(raw []byte, limit uint32) bool {
// 自定义检测逻辑 - 检查前4个字节是否是0x01,0x02,0x03,0x04
return len(raw) > 3 &&
raw[0] == 0x01 &&
raw[1] == 0x02 &&
raw[2] == 0x03 &&
raw[3] == 0x04
})
// 将自定义检测器添加到检测树中
mimetype.Extend(customMIME)
// 测试自定义类型
data := []byte{0x01, 0x02, 0x03, 0x04, 0x05}
mtype := mimetype.Detect(data)
fmt.Println(mtype) // application/x-custom
}
2. 限制检测深度
对于大文件,可以限制检测的字节数以提高性能:
file, _ := os.Open("largefile.bin")
defer file.Close()
// 只检测前1024字节
mtype, _ := mimetype.DetectReader(file)
fmt.Println(mtype)
3. 获取检测器层次结构
mtype := mimetype.Detect([]byte("<?xml version="1.0"?>"))
for mtype != nil {
fmt.Println(mtype.String())
mtype = mtype.Parent()
}
// 输出可能是:
// application/xml
// text/plain; charset=utf-8
性能优化
- 复用检测器:对于多次检测,可以复用
mimetype.Detector
实例
detector := mimetype.NewDetector(
mimetype.DetectJPEG,
mimetype.DetectPNG,
mimetype.DetectPDF,
)
data := []byte{0xFF, 0xD8, 0xFF} // JPEG开头
mtype := detector.Detect(data)
fmt.Println(mtype) // image/jpeg
- 限制检测类型:只检测你关心的类型
// 只检测图片类型
mtype := mimetype.Detect(
[]byte{0x89, 0x50, 0x4E, 0x47},
mimetype.DetectImage,
)
fmt.Println(mtype) // image/png
常见MIME类型检测示例
func detectCommonFiles() {
// JPEG图片
jpegData := []byte{0xFF, 0xD8, 0xFF}
fmt.Println("JPEG:", mimetype.Detect(jpegData))
// PNG图片
pngData := []byte{0x89, 0x50, 0x4E, 0x47}
fmt.Println("PNG:", mimetype.Detect(pngData))
// PDF文档
pdfData := []byte{0x25, 0x50, 0x44, 0x46}
fmt.Println("PDF:", mimetype.Detect(pdfData))
// ZIP压缩文件
zipData := []byte{0x50, 0x4B, 0x03, 0x04}
fmt.Println("ZIP:", mimetype.Detect(zipData))
// MP3音频
mp3Data := []byte{0x49, 0x44, 0x33}
fmt.Println("MP3:", mimetype.Detect(mp3Data))
}
总结
mimetype
库提供了强大而灵活的文件类型检测功能,主要特点包括:
- 基于魔法数字检测,不依赖文件扩展名
- 支持自定义类型检测器
- 高效处理大文件
- 提供类型层次结构信息
- 支持限制检测范围提高性能
对于需要可靠文件类型检测的Go应用程序,mimetype
是一个优秀的解决方案。