golang通过魔数签名检测文件类型的插件库filetype的使用
Golang通过魔数签名检测文件类型的插件库filetype的使用
filetype是一个小型且无依赖的Go包,用于通过检查魔数签名来推断文件和MIME类型。
特性
- 支持广泛的文件类型
- 提供文件扩展名和正确的MIME类型
- 通过扩展名或MIME类型发现文件
- 通过类别(图像、视频、音频等)发现文件
- 提供大量帮助程序和文件匹配快捷方式
- 可插拔:添加自定义新类型和匹配器
- 简单语义化的API
- 处理大文件时速度极快
- 只需要前262字节(最大文件头),所以可以只传递一个切片
- 无依赖(纯Go代码,无需C编译)
- 跨平台文件识别
安装
go get github.com/h2non/filetype
使用示例
简单文件类型检查
package main
import (
"fmt"
"io/ioutil"
"github.com/h2non/filetype"
)
func main() {
buf, _ := ioutil.ReadFile("sample.jpg")
kind, _ := filetype.Match(buf)
if kind == filetype.Unknown {
fmt.Println("Unknown file type")
return
}
fmt.Printf("File type: %s. MIME: %s\n", kind.Extension, kind.MIME.Value)
}
检查类型类别
package main
import (
"fmt"
"io/ioutil"
"github.com/h2non/filetype"
)
func main() {
buf, _ := ioutil.ReadFile("sample.jpg")
if filetype.IsImage(buf) {
fmt.Println("File is an image")
} else {
fmt.Println("Not an image")
}
}
检查支持的类型
package main
import (
"fmt"
"github.com/h2non/filetype"
)
func main() {
// 通过扩展名检查文件是否支持
if filetype.IsSupported("jpg") {
fmt.Println("Extension supported")
} else {
fmt.Println("Extension not supported")
}
// 通过MIME类型检查文件是否支持
if filetype.IsMIMESupported("image/jpeg") {
fmt.Println("MIME type supported")
} else {
fmt.Println("MIME type not supported")
}
}
文件头检查
package main
import (
"fmt"
"os"
"github.com/h2non/filetype"
)
func main() {
// 打开文件描述符
file, _ := os.Open("movie.mp4")
// 只需要传递文件头 = 前261字节
head := make([]byte, 261)
file.Read(head)
if filetype.IsImage(head) {
fmt.Println("File is an image")
} else {
fmt.Println("Not an image")
}
}
添加自定义文件类型匹配器
package main
import (
"fmt"
"github.com/h2non/filetype"
)
var fooType = filetype.NewType("foo", "foo/foo")
func fooMatcher(buf []byte) bool {
return len(buf) > 1 && buf[0] == 0x01 && buf[1] == 0x02
}
func main() {
// 注册新的匹配器和类型
filetype.AddMatcher(fooType, fooMatcher)
// 检查新类型是否通过扩展名支持
if filetype.IsSupported("foo") {
fmt.Println("New supported type: foo")
}
// 检查新类型是否通过MIME支持
if filetype.IsMIMESupported("foo/foo") {
fmt.Println("New supported MIME type: foo/foo")
}
// 尝试匹配文件
fooFile := []byte{0x01, 0x02}
kind, _ := filetype.Match(fooFile)
if kind == filetype.Unknown {
fmt.Println("Unknown file type")
} else {
fmt.Printf("File type matched: %s\n", kind.Extension)
}
}
支持的文件类型
图像
- jpg - image/jpeg
- png - image/png
- gif - image/gif
- webp - image/webp
- cr2 - image/x-canon-cr2
- tif - image/tiff
- bmp - image/bmp
- heif - image/heif
- jxr - image/vnd.ms-photo
- psd - image/vnd.adobe.photoshop
- ico - image/vnd.microsoft.icon
- dwg - image/vnd.dwg
- avif - image/avif
视频
- mp4 - video/mp4
- m4v - video/x-m4v
- mkv - video/x-matroska
- webm - video/webm
- mov - video/quicktime
- avi - video/x-msvideo
- wmv - video/x-ms-wmv
- mpg - video/mpeg
- flv - video/x-flv
- 3gp - video/3gpp
音频
- mid - audio/midi
- mp3 - audio/mpeg
- m4a - audio/mp4
- ogg - audio/ogg
- flac - audio/x-flac
- wav - audio/x-wav
- amr - audio/amr
- aac - audio/aac
- aiff - audio/x-aiff
归档
- epub - application/epub+zip
- zip - application/zip
- tar - application/x-tar
- rar - application/vnd.rar
- gz - application/gzip
- bz2 - application/x-bzip2
- 7z - application/x-7z-compressed
- xz - application/x-xz
- zstd - application/zstd
- pdf - application/pdf
- exe - application/vnd.microsoft.portable-executable
- swf - application/x-shockwave-flash
- rtf - application/rtf
- iso - application/x-iso9660-image
- eot - application/octet-stream
- ps - application/postscript
- sqlite - application/vnd.sqlite3
- nes - application/x-nintendo-nes-rom
- crx - application/x-google-chrome-extension
- cab - application/vnd.ms-cab-compressed
- deb - application/vnd.debian.binary-package
- ar - application/x-unix-archive
- Z - application/x-compress
- lz - application/x-lzip
- rpm - application/x-rpm
- elf - application/x-executable
- dcm - application/dicom
文档
- doc - application/msword
- docx - application/vnd.openxmlformats-officedocument.wordprocessingml.document
- xls - application/vnd.ms-excel
- xlsx - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- ppt - application/vnd.ms-powerpoint
- pptx - application/vnd.openxmlformats-officedocument.presentationml.presentation
字体
- woff - application/font-woff
- woff2 - application/font-woff
- ttf - application/font-sfnt
- otf - application/font-sfnt
应用程序
- wasm - application/wasm
- dex - application/vnd.android.dex
- dey - application/vnd.android.dey
- parquet - application/vnd.apache.parquet
更多关于golang通过魔数签名检测文件类型的插件库filetype的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang通过魔数签名检测文件类型的插件库filetype的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang文件类型检测库filetype使用指南
filetype是一个基于魔数(magic number)签名的Golang文件类型检测库,它可以快速准确地识别文件类型而不仅仅依赖文件扩展名。
安装
go get github.com/h2non/filetype
基本使用
1. 检测已知文件类型
package main
import (
"fmt"
"io/ioutil"
"github.com/h2non/filetype"
)
func main() {
// 读取文件内容
buf, _ := ioutil.ReadFile("sample.jpg")
// 检测文件类型
kind, _ := filetype.Match(buf)
if kind == filetype.Unknown {
fmt.Println("Unknown file type")
return
}
fmt.Printf("File type: %s. MIME: %s\n", kind.Extension, kind.MIME.Value)
}
2. 检查特定文件类型
// 检查是否是JPEG图片
if filetype.IsImage(buf) {
fmt.Println("File is an image")
}
// 更精确的检查
if filetype.Is(buf, "jpg") {
fmt.Println("File is a JPEG image")
}
// 检查MIME类型
if filetype.IsMIME(buf, "image/jpeg") {
fmt.Println("File is a JPEG image")
}
高级功能
1. 自定义类型检测
package main
import (
"fmt"
"github.com/h2non/filetype"
"github.com/h2non/filetype/types"
)
// 定义自定义文件类型
var FooType = types.Type{
Extension: "foo",
MIME: types.MIME{Type: "application", Value: "foo"},
}
// 自定义匹配函数
func fooMatcher(buf []byte) bool {
return len(buf) > 1 && buf[0] == 0x01 && buf[1] == 0x02
}
func main() {
// 注册自定义类型
filetype.AddMatcher(FooType, fooMatcher)
// 现在可以检测自定义类型了
buf := []byte{0x01, 0x02}
kind, _ := filetype.Match(buf)
if kind == FooType {
fmt.Println("File is a foo file")
}
}
2. 从Reader检测
package main
import (
"fmt"
"os"
"github.com/h2non/filetype"
)
func main() {
file, _ := os.Open("sample.png")
defer file.Close()
// 从reader检测
head := make([]byte, 261) // 需要足够大的缓冲区
file.Read(head)
kind, _ := filetype.Match(head)
fmt.Printf("File type: %s\n", kind.Extension)
}
3. 文件类型分类检查
buf, _ := ioutil.ReadFile("sample.pdf")
if filetype.IsArchive(buf) {
fmt.Println("File is an archive")
} else if filetype.IsAudio(buf) {
fmt.Println("File is an audio")
} else if filetype.IsDocument(buf) {
fmt.Println("File is a document")
} else if filetype.IsFont(buf) {
fmt.Println("File is a font")
} else if filetype.IsImage(buf) {
fmt.Println("File is an image")
} else if filetype.IsVideo(buf) {
fmt.Println("File is a video")
}
性能优化
对于大文件,不需要读取整个文件,只需要读取文件头部即可:
func readFileHeader(filePath string) ([]byte, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
// 只需要前261字节即可识别大多数文件类型
head := make([]byte, 261)
_, err = file.Read(head)
if err != nil {
return nil, err
}
return head, nil
}
支持的格式
filetype支持检测多种常见格式,包括但不限于:
- 图片: jpg, png, gif, webp, bmp, ico等
- 视频: mp4, webm, mkv, mov, avi等
- 音频: mp3, flac, ogg, wav, amr等
- 文档: pdf, docx, pptx, xlsx等
- 压缩文件: zip, tar, rar, gz, bz2等
- 字体: ttf, woff, woff2等
总结
filetype是一个功能强大且易于使用的文件类型检测库,它通过分析文件内容的魔数签名来准确识别文件类型,比依赖文件扩展名更可靠。它支持扩展自定义类型检测,并针对性能进行了优化,适合在生产环境中使用。