276 lines
6.7 KiB
Markdown
276 lines
6.7 KiB
Markdown
|
# 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)
|
||
|
|
||
|
Small 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.
|
||
|
|
||
|
For SVG file type checking, see [go-is-svg](https://github.com/h2non/go-is-svg) package.
|
||
|
|
||
|
## Features
|
||
|
|
||
|
- Supports a [wide range](#supported-types) 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-additional-file-type-matchers): add custom new types and matchers
|
||
|
- Simple and semantic API
|
||
|
- [Blazing fast](#benchmarks), even processing large files
|
||
|
- Only first 261 bytes representing the max file header is required, so you can just [pass a slice](#file-header)
|
||
|
- Dependency free (just Go code, no C compilation needed)
|
||
|
- Cross-platform file recognition
|
||
|
|
||
|
## Installation
|
||
|
|
||
|
```bash
|
||
|
go get gopkg.in/h2non/filetype.v1
|
||
|
```
|
||
|
|
||
|
## API
|
||
|
|
||
|
See [Godoc](https://godoc.org/github.com/h2non/filetype) reference.
|
||
|
|
||
|
### Subpackages
|
||
|
|
||
|
- [`gopkg.in/h2non/filetype.v1/types`](https://godoc.org/github.com/h2non/filetype/types)
|
||
|
- [`gopkg.in/h2non/filetype.v1/matchers`](https://godoc.org/github.com/h2non/filetype/matchers)
|
||
|
|
||
|
## Examples
|
||
|
|
||
|
#### Simple file type checking
|
||
|
|
||
|
```go
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"gopkg.in/h2non/filetype.v1"
|
||
|
"io/ioutil"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
buf, _ := ioutil.ReadFile("sample.jpg")
|
||
|
|
||
|
kind, unknown := filetype.Match(buf)
|
||
|
if unknown != nil {
|
||
|
fmt.Printf("Unknown: %s", unknown)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
fmt.Printf("File type: %s. MIME: %s\n", kind.Extension, kind.MIME.Value)
|
||
|
}
|
||
|
```
|
||
|
|
||
|
#### Check type class
|
||
|
|
||
|
```go
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"gopkg.in/h2non/filetype.v1"
|
||
|
"io/ioutil"
|
||
|
)
|
||
|
|
||
|
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
|
||
|
|
||
|
```go
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"gopkg.in/h2non/filetype.v1"
|
||
|
)
|
||
|
|
||
|
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
|
||
|
|
||
|
```go
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"gopkg.in/h2non/filetype.v1"
|
||
|
"io/ioutil"
|
||
|
)
|
||
|
|
||
|
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
|
||
|
|
||
|
```go
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"gopkg.in/h2non/filetype.v1"
|
||
|
)
|
||
|
|
||
|
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`
|
||
|
- **jxr** - `image/vnd.ms-photo`
|
||
|
- **psd** - `image/vnd.adobe.photoshop`
|
||
|
- **ico** - `image/x-icon`
|
||
|
|
||
|
#### 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`
|
||
|
|
||
|
#### Audio
|
||
|
|
||
|
- **mid** - `audio/midi`
|
||
|
- **mp3** - `audio/mpeg`
|
||
|
- **m4a** - `audio/m4a`
|
||
|
- **ogg** - `audio/ogg`
|
||
|
- **flac** - `audio/x-flac`
|
||
|
- **wav** - `audio/x-wav`
|
||
|
- **amr** - `audio/amr`
|
||
|
|
||
|
#### Archive
|
||
|
|
||
|
- **epub** - `application/epub+zip`
|
||
|
- **zip** - `application/zip`
|
||
|
- **tar** - `application/x-tar`
|
||
|
- **rar** - `application/x-rar-compressed`
|
||
|
- **gz** - `application/gzip`
|
||
|
- **bz2** - `application/x-bzip2`
|
||
|
- **7z** - `application/x-7z-compressed`
|
||
|
- **xz** - `application/x-xz`
|
||
|
- **pdf** - `application/pdf`
|
||
|
- **exe** - `application/x-msdownload`
|
||
|
- **swf** - `application/x-shockwave-flash`
|
||
|
- **rtf** - `application/rtf`
|
||
|
- **eot** - `application/octet-stream`
|
||
|
- **ps** - `application/postscript`
|
||
|
- **sqlite** - `application/x-sqlite3`
|
||
|
- **nes** - `application/x-nintendo-nes-rom`
|
||
|
- **crx** - `application/x-google-chrome-extension`
|
||
|
- **cab** - `application/vnd.ms-cab-compressed`
|
||
|
- **deb** - `application/x-deb`
|
||
|
- **ar** - `application/x-unix-archive`
|
||
|
- **Z** - `application/x-compress`
|
||
|
- **lz** - `application/x-lzip`
|
||
|
- **rpm** - `application/x-rpm`
|
||
|
- **elf** - `application/x-executable`
|
||
|
|
||
|
#### 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`
|
||
|
|
||
|
## Benchmarks
|
||
|
|
||
|
Measured using [real files](https://github.com/h2non/filetype/tree/master/fixtures).
|
||
|
|
||
|
Environment: OSX x64 i7 2.7 Ghz
|
||
|
|
||
|
```bash
|
||
|
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
|