go get github.com/gabriel-vasile/mimetype
The library exposes three functions you can use in order to detect a file type. See Godoc for full reference.
func Detect(in []byte) (mime, extension string) {...}
func DetectReader(r io.Reader) (mime, extension string, err error) {...}
func DetectFile(file string) (mime, extension string, err error) {...}
When detecting from a ReadSeeker
interface, such as os.File
, make sure
to reset the offset of the reader to the beginning if needed:
_, err = file.Seek(io.SeekStart, 0)
If, for example, you need to detect the "text/foobar" mime, for text files containing the string "foobar" at the start of their first line:
- create the matching function
foobar := func(input []byte) bool { return bytes.HasPrefix(input, []byte("foobar")) }
- create the mime type node
foobarNode := mimetype.NewNode("text/foobar", "fbExt", foobar)
- append the new node in the tree
mimetype.Txt.Append(foobarNode)
- detect
mime, extension := mimetype.Detect([]byte("foobar\nfoo foo bar"))
See TestAppend for a working example. See Contributing if you consider the missing mime type should be included in the library by default.
mimetype uses an hierarchical structure to keep the matching functions. This reduces the number of calls needed for detecting the file type. The reason behind this choice is that there are file formats used as containers for other file formats. For example, Microsoft office files are just zip archives, containing specific metadata files.
See CONTRIBUTING.md.