「Go开源包」mimetype:一个支持172种MIME类型检测的包
大家好,我是 Go学堂 渔夫子。
今天给大家推荐一个Go的开源包:mimetype,一个快速的检测媒体类型和文件类型的包,共支持172种MIME类型。例如,检测是否是Content-Type是否json格式还是text/plain格式,亦或者是text/html、xml等。
该包星标1.1k,有51个贡献者,4.1k的开源包在使用。 项目地址:github.com/gabriel-vas…
支持的MIME类型
下面是截取一部分支持的类型,详细的类型可参考链接:github.com/gabriel-vas…
基础使用
首先,引入该包
go get github.com/gabriel-vasile/mimetype
然后调用该包定义的Detect函数即可。Detect函数可以基于字节数组、文件进行检测。但其底层原理都是先将内容读取出来,然后再根据已定义的类型类依次进行对应的特征匹配。
import (
"bytes"
"fmt"
"os"
"github.com/gabriel-vasile/mimetype"
)
func main() {
testBytes := []byte("This random text has a MIME type of text/plain; charset=utf-8.")
mtype := mimetype.Detect(testBytes)
fmt.Println(mtype.Is("text/plain"), mtype.String(), mtype.Extension())
mtype, err := mimetype.DetectReader(bytes.NewReader(testBytes))
fmt.Println(mtype.Is("text/plain"), mtype.String(), mtype.Extension(), err)
mtype, err = mimetype.DetectFile("a nonexistent file")
fmt.Println(mtype.Is("application/octet-stream"), mtype.String(), os.IsNotExist(err))
}
上面代码输出:
true text/plain; charset=utf-8 .txt
true text/plain; charset=utf-8 .txt <nil>
true application/octet-stream true
常见问题
mimetype包在监测文件的内容类型时,明明在支持的类型列表中,但却检测不到。这是因为有的文件类型的格式是写在文件的末尾的,mimetype在读取内容的时候并不是将文件的内容全部读取到内存的(因为大多数类型标识都是写在文件头部的),这时只要通过以下代码增大读取的大小即可:
mimetype.SetLimit(1024*1024) // Set limit to 1MB.
// or
mimetype.SetLimit(0) // No limit, whole file content used.
mimetype.DetectFile("file.doc")
设计理念
在检测逻辑中,mimetype包使用了分层结构设计,以减少在检测过程中的调用次数,提高性能。采用这种设计的原因是因为文件的类型可以按这种结构进行组织。比如,所有的Office文件都是zip类型的,并且通过一个metadata描述具体的类型。这样,在检测的过程中,只要检测到了zip类型,就不需要再检测是否是文本类型的文件了。然后再深入检测具体的office类型即可。如下:
**特别说明:**你的关注,是我写下去的最大动力。关注 Go学堂 送《100个go常见的错误》pdf文档、经典go学习资料。
转载自:https://juejin.cn/post/7233413563465056293