1# filetype [![Build Status](https://travis-ci.org/h2non/filetype.png)](https://travis-ci.org/h2non/filetype) [![GoDoc](https://godoc.org/github.com/h2non/filetype?status.svg)](https://godoc.org/github.com/h2non/filetype) [![Go Report Card](http://goreportcard.com/badge/h2non/filetype)](http://goreportcard.com/report/h2non/filetype) [![Go Version](https://img.shields.io/badge/go-v1.0+-green.svg?style=flat)](https://github.com/h2non/gentleman) 2 3Small and dependency free [Go](https://golang.org) package to infer file and MIME type checking the [magic numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) signature. 4 5For SVG file type checking, see [go-is-svg](https://github.com/h2non/go-is-svg) package. 6 7## Features 8 9- Supports a [wide range](#supported-types) of file types 10- Provides file extension and proper MIME type 11- File discovery by extension or MIME type 12- File discovery by class (image, video, audio...) 13- Provides a bunch of helpers and file matching shortcuts 14- [Pluggable](#add-additional-file-type-matchers): add custom new types and matchers 15- Simple and semantic API 16- [Blazing fast](#benchmarks), even processing large files 17- Only first 261 bytes representing the max file header is required, so you can just [pass a slice](#file-header) 18- Dependency free (just Go code, no C compilation needed) 19- Cross-platform file recognition 20 21## Installation 22 23```bash 24go get gopkg.in/h2non/filetype.v1 25``` 26 27## API 28 29See [Godoc](https://godoc.org/github.com/h2non/filetype) reference. 30 31### Subpackages 32 33- [`gopkg.in/h2non/filetype.v1/types`](https://godoc.org/github.com/h2non/filetype/types) 34- [`gopkg.in/h2non/filetype.v1/matchers`](https://godoc.org/github.com/h2non/filetype/matchers) 35 36## Examples 37 38#### Simple file type checking 39 40```go 41package main 42 43import ( 44 "fmt" 45 "gopkg.in/h2non/filetype.v1" 46 "io/ioutil" 47) 48 49func main() { 50 buf, _ := ioutil.ReadFile("sample.jpg") 51 52 kind, unkwown := filetype.Match(buf) 53 if unkwown != nil { 54 fmt.Printf("Unkwown: %s", unkwown) 55 return 56 } 57 58 fmt.Printf("File type: %s. MIME: %s\n", kind.Extension, kind.MIME.Value) 59} 60``` 61 62#### Check type class 63 64```go 65package main 66 67import ( 68 "fmt" 69 "gopkg.in/h2non/filetype.v1" 70 "io/ioutil" 71) 72 73func main() { 74 buf, _ := ioutil.ReadFile("sample.jpg") 75 76 if filetype.IsImage(buf) { 77 fmt.Println("File is an image") 78 } else { 79 fmt.Println("Not an image") 80 } 81} 82``` 83 84#### Supported type 85 86```go 87package main 88 89import ( 90 "fmt" 91 "gopkg.in/h2non/filetype.v1" 92) 93 94func main() { 95 // Check if file is supported by extension 96 if filetype.IsSupported("jpg") { 97 fmt.Println("Extension supported") 98 } else { 99 fmt.Println("Extension not supported") 100 } 101 102 // Check if file is supported by extension 103 if filetype.IsMIMESupported("image/jpeg") { 104 fmt.Println("MIME type supported") 105 } else { 106 fmt.Println("MIME type not supported") 107 } 108} 109``` 110 111#### File header 112 113```go 114package main 115 116import ( 117 "fmt" 118 "gopkg.in/h2non/filetype.v1" 119 "io/ioutil" 120) 121 122func main() { 123 // Read a file 124 buf, _ := ioutil.ReadFile("sample.jpg") 125 126 // We only have to pass the file header = first 261 bytes 127 head := buf[:261] 128 129 if filetype.IsImage(head) { 130 fmt.Println("File is an image") 131 } else { 132 fmt.Println("Not an image") 133 } 134} 135``` 136 137#### Add additional file type matchers 138 139```go 140package main 141 142import ( 143 "fmt" 144 "gopkg.in/h2non/filetype.v1" 145) 146 147var fooType = filetype.NewType("foo", "foo/foo") 148 149func fooMatcher(buf []byte) bool { 150 return len(buf) > 1 && buf[0] == 0x01 && buf[1] == 0x02 151} 152 153func main() { 154 // Register the new matcher and its type 155 filetype.AddMatcher(fooType, fooMatcher) 156 157 // Check if the new type is supported by extension 158 if filetype.IsSupported("foo") { 159 fmt.Println("New supported type: foo") 160 } 161 162 // Check if the new type is supported by MIME 163 if filetype.IsMIMESupported("foo/foo") { 164 fmt.Println("New supported MIME type: foo/foo") 165 } 166 167 // Try to match the file 168 fooFile := []byte{0x01, 0x02} 169 kind, _ := filetype.Match(fooFile) 170 if kind == filetype.Unknown { 171 fmt.Println("Unknown file type") 172 } else { 173 fmt.Printf("File type matched: %s\n", kind.Extension) 174 } 175} 176``` 177 178## Supported types 179 180#### Image 181 182- **jpg** - `image/jpeg` 183- **png** - `image/png` 184- **gif** - `image/gif` 185- **webp** - `image/webp` 186- **cr2** - `image/x-canon-cr2` 187- **tif** - `image/tiff` 188- **bmp** - `image/bmp` 189- **jxr** - `image/vnd.ms-photo` 190- **psd** - `image/vnd.adobe.photoshop` 191- **ico** - `image/x-icon` 192 193#### Video 194 195- **mp4** - `video/mp4` 196- **m4v** - `video/x-m4v` 197- **mkv** - `video/x-matroska` 198- **webm** - `video/webm` 199- **mov** - `video/quicktime` 200- **avi** - `video/x-msvideo` 201- **wmv** - `video/x-ms-wmv` 202- **mpg** - `video/mpeg` 203- **flv** - `video/x-flv` 204 205#### Audio 206 207- **mid** - `audio/midi` 208- **mp3** - `audio/mpeg` 209- **m4a** - `audio/m4a` 210- **ogg** - `audio/ogg` 211- **flac** - `audio/x-flac` 212- **wav** - `audio/x-wav` 213- **amr** - `audio/amr` 214 215#### Archive 216 217- **epub** - `application/epub+zip` 218- **zip** - `application/zip` 219- **tar** - `application/x-tar` 220- **rar** - `application/x-rar-compressed` 221- **gz** - `application/gzip` 222- **bz2** - `application/x-bzip2` 223- **7z** - `application/x-7z-compressed` 224- **xz** - `application/x-xz` 225- **pdf** - `application/pdf` 226- **exe** - `application/x-msdownload` 227- **swf** - `application/x-shockwave-flash` 228- **rtf** - `application/rtf` 229- **eot** - `application/octet-stream` 230- **ps** - `application/postscript` 231- **sqlite** - `application/x-sqlite3` 232- **nes** - `application/x-nintendo-nes-rom` 233- **crx** - `application/x-google-chrome-extension` 234- **cab** - `application/vnd.ms-cab-compressed` 235- **deb** - `application/x-deb` 236- **ar** - `application/x-unix-archive` 237- **Z** - `application/x-compress` 238- **lz** - `application/x-lzip` 239- **rpm** - `application/x-rpm` 240- **elf** - `application/x-executable` 241 242#### Font 243 244- **woff** - `application/font-woff` 245- **woff2** - `application/font-woff` 246- **ttf** - `application/font-sfnt` 247- **otf** - `application/font-sfnt` 248 249## Benchmarks 250 251Measured using [real files](https://github.com/h2non/filetype/tree/master/fixtures). 252 253Environment: OSX x64 i7 2.7 Ghz 254 255```bash 256BenchmarkMatchTar-8 1000000 1083 ns/op 257BenchmarkMatchZip-8 1000000 1162 ns/op 258BenchmarkMatchJpeg-8 1000000 1280 ns/op 259BenchmarkMatchGif-8 1000000 1315 ns/op 260BenchmarkMatchPng-8 1000000 1121 ns/op 261``` 262 263## License 264 265MIT - Tomas Aparicio 266