likes
comments
collection
share

「Go开源包」mimetype:一个支持172种MIME类型检测的包

作者站长头像
站长
· 阅读数 29

大家好,我是 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开源包」mimetype:一个支持172种MIME类型检测的包

基础使用

首先,引入该包

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开源包」mimetype:一个支持172种MIME类型检测的包

**特别说明:**你的关注,是我写下去的最大动力。关注 Go学堂 送《100个go常见的错误》pdf文档、经典go学习资料。