README

filetype Build Status GoDoc Go Report Card Go Version

Small and dependency free Go package to infer file and MIME type checking the magic numbers signature.

For SVG file type checking, see go-is-svg package. Python port: filetype.py.

Features

  • Supports a wide range of file types
  • Provides file extension and proper MIME type
  • File discovery by extension or MIME type
  • File discovery by class (image, video, audio...)
  • Provides a bunch of helpers and file matching shortcuts
  • Pluggable: add custom new types and matchers
  • Simple and semantic API
  • Blazing fast, even processing large files
  • Only first 262 bytes representing the max file header is required, so you can just pass a slice
  • Dependency free (just Go code, no C compilation needed)
  • Cross-platform file recognition

Installation

go get github.com/h2non/filetype

API

See Godoc reference.

Subpackages

Examples

Simple file type checking
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)
}
Check type class
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")
  }
}
Supported type
package main

import (
  "fmt"

  "github.com/h2non/filetype"
)

func main() {
  // Check if file is supported by extension
  if filetype.IsSupported("jpg") {
    fmt.Println("Extension supported")
  } else {
    fmt.Println("Extension not supported")
  }

  // Check if file is supported by extension
  if filetype.IsMIMESupported("image/jpeg") {
    fmt.Println("MIME type supported")
  } else {
    fmt.Println("MIME type not supported")
  }
}
File header
package main

import (
  "fmt"
  "io/ioutil"

  "github.com/h2non/filetype"
)

func main() {
  // Open a file descriptor
  file, _ := os.Open("movie.mp4")

  // We only have to pass the file header = first 261 bytes
  head := make([]byte, 261)
  file.Read(head)

  if filetype.IsImage(head) {
    fmt.Println("File is an image")
  } else {
    fmt.Println("Not an image")
  }
}
Add additional file type matchers
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() {
  // Register the new matcher and its type
  filetype.AddMatcher(fooType, fooMatcher)

  // Check if the new type is supported by extension
  if filetype.IsSupported("foo") {
    fmt.Println("New supported type: foo")
  }

  // Check if the new type is supported by MIME
  if filetype.IsMIMESupported("foo/foo") {
    fmt.Println("New supported MIME type: foo/foo")
  }

  // Try to match the file
  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)
  }
}

Supported types

Image
  • 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
Video
  • 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
Audio
  • mid - audio/midi
  • mp3 - audio/mpeg
  • m4a - audio/m4a
  • ogg - audio/ogg
  • flac - audio/x-flac
  • wav - audio/x-wav
  • amr - audio/amr
  • aac - audio/aac
Archive
  • 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
  • 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
Documents
  • 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
Font
  • woff - application/font-woff
  • woff2 - application/font-woff
  • ttf - application/font-sfnt
  • otf - application/font-sfnt
Application
  • wasm - application/wasm
  • dex - application/vnd.android.dex
  • dey - application/vnd.android.dey

Benchmarks

Measured using real files.

Environment: OSX x64 i7 2.7 Ghz

BenchmarkMatchTar-8    1000000        1083 ns/op
BenchmarkMatchZip-8    1000000        1162 ns/op
BenchmarkMatchJpeg-8   1000000        1280 ns/op
BenchmarkMatchGif-8    1000000        1315 ns/op
BenchmarkMatchPng-8    1000000        1121 ns/op

License

MIT - Tomas Aparicio

Documentation

Index

Constants

View Source
const Version = "1.1.1"

Version exposes the current package version.

Variables

View Source
var ErrEmptyBuffer = errors.New("Empty buffer")

ErrEmptyBuffer represents an empty buffer error

View Source
var ErrUnknownBuffer = errors.New("Unknown buffer type")

ErrUnknownBuffer represents a unknown buffer error

View Source
var MatcherKeys = &matchers.MatcherKeys

MatcherKeys is an alias to matchers.MatcherKeys

View Source
var Matchers = matchers.Matchers

Matchers is an alias to matchers.Matchers

View Source
var NewMatcher = matchers.NewMatcher

NewMatcher is an alias to matchers.NewMatcher

View Source
var NewType = types.NewType

NewType creates and registers a new type

View Source
var Types = types.Types

Types stores a map of supported types

View Source
var Unknown = types.Unknown

Unknown represents an unknown file type

Functions

func AddMatcher

func AddMatcher(fileType types.Type, matcher matchers.Matcher) matchers.TypeMatcher

AddMatcher registers a new matcher type

func AddType

func AddType(ext, mime string) types.Type

AddType registers a new file type

func Archive

func Archive(buf []byte) (types.Type, error)

Archive tries to match a file as generic archive type

func Audio

func Audio(buf []byte) (types.Type, error)

Audio tries to match a file as audio type

func Document

func Document(buf []byte) (types.Type, error)

Document tries to match a file as document type

func Font

func Font(buf []byte) (types.Type, error)

Font tries to match a file as text font type

func Get

func Get(buf []byte) (types.Type, error)

Get is an alias to Match()

func GetType

func GetType(ext string) types.Type

GetType retrieves a Type by file extension

func Image

func Image(buf []byte) (types.Type, error)

Image tries to match a file as image type

func Is

func Is(buf []byte, ext string) bool

Is checks if a given buffer matches with the given file type extension

func IsArchive

func IsArchive(buf []byte) bool

IsArchive checks if the given buffer is an archive type

func IsAudio

func IsAudio(buf []byte) bool

IsAudio checks if the given buffer is an audio type

func IsDocument

func IsDocument(buf []byte) bool

IsDocument checks if the given buffer is an document type

func IsExtension

func IsExtension(buf []byte, ext string) bool

IsExtension semantic alias to Is()

func IsFont

func IsFont(buf []byte) bool

IsFont checks if the given buffer is a font type

func IsImage

func IsImage(buf []byte) bool

IsImage checks if the given buffer is an image type

func IsMIME

func IsMIME(buf []byte, mime string) bool

IsMIME checks if a given buffer matches with the given MIME type

func IsMIMESupported

func IsMIMESupported(mime string) bool

IsMIMESupported checks if a given MIME type is supported

func IsSupported

func IsSupported(ext string) bool

IsSupported checks if a given file extension is supported

func IsType

func IsType(buf []byte, kind types.Type) bool

IsType checks if a given buffer matches with the given file type

func IsVideo

func IsVideo(buf []byte) bool

IsVideo checks if the given buffer is a video type

func Match

func Match(buf []byte) (types.Type, error)

Match infers the file type of a given buffer inspecting its magic numbers signature

func MatchFile

func MatchFile(filepath string) (types.Type, error)

MatchFile infers a file type for a file

func MatchMap

func MatchMap(buf []byte, matchers matchers.Map) types.Type

MatchMap performs a file matching against a map of match functions

func MatchReader

func MatchReader(reader io.Reader) (types.Type, error)

MatchReader is convenient wrapper to Match() any Reader

func Matches

func Matches(buf []byte) bool

Matches checks if the given buffer matches with some supported file type

func MatchesMap

func MatchesMap(buf []byte, matchers matchers.Map) bool

MatchesMap is an alias to Matches() but using matching against a map of match functions

func Video

func Video(buf []byte) (types.Type, error)

Video tries to match a file as video type

Types

This section is empty.

Directories

Path Synopsis