はじめに
こちらはzennの記事の転載となります。
平下CTO@sweeepです。Go言語でよく使うファイルのValidation方法などについて解説します。
本記事の内容です。
- ファイルサイズチェック
- ファイルのValidation
- ファイル拡張子からContentTypeへの変換
- 使い方
- 実行結果
ファイルサイズチェック
定義済みファイルサイズより大きければファイルサイズとエラーを返します。問題なければファイルサイズとnilを返します。
const (
MaxSize = 10 * 1024 * 1024 // 10MB
)
var (
ErrFileSize = errors.New("file size error")
)
func CheckFileSize(size int64) (int64, error) {
if size > MaxSize { // MaxSizeより大きい場合はエラー
return size, fmt.Errorf("size: %v error: %w", size, ErrFileSize)
}
return size, nil
}
ファイルのValidation
GoのhttpパッケージのDetectContentTypeという関数を利用します。
https://pkg.go.dev/net/http#DetectContentType
以下のように*[]byteを渡してMIMEタイプ:メディアタイプを取得します。
mine := http.DetectContentType(*data)
下記はJPEG or PNGを許可する場合、取得したMIMEタイプをチェックし、該当した場合はJEPG or PNGのMINEタイプとnilを、該当しない場合は取得したMINEタイプとエラーを返します。
var (
JPEG = "image/jpeg"
PNG = "image/png"
)
func ValidateFile(data *[]byte) (string, error) {
mine := http.DetectContentType(*data)
switch {
case mine == JPEG: // MINEタイプimage/jpeg
return mine, nil
case mine == PNG: // MINEタイプがimage/png
return mine, nil
default:
return mine, fmt.Errorf("mine: %v error: %w", mine, ErrValidation)
}
}
ファイル拡張子からContentTypeへの変換
HTTPヘッダーにContent-TypeへリソースのMIMEタイプ埋めて返したい場合があると思います。
まずは以下の関数でファイル名から拡張子を取得します。
func ExtractExt(name string) string {
pos := strings.LastIndex(name, ".")
// .から後ろをスライスで取得
return name[pos:]
}
ファイルの拡張子から該当した場合はJPEG or PNGのMINEタイプを、該当しない場合は取得した拡張子を返します。
var (
JPG = "image/jpeg"
PNG = "image/png"
ExtJPG = ".jpg"
ExtJPEG = ".jpeg"
ExtPNG = ".png"
)
func ExtToContentType(ext string) (string, error) {
switch {
case ext == ExtJPG: // 拡張子が".jpg"の場合 ContentType:image/jpeg
return JPEG, nil
case ext == ExtJPEG: // 拡張子が".jpeg"の場合 ContentType:image/jpeg
return JPEG, nil
case ext == ExtPNG: // 拡張子が".png"の場合 ContentType:image/png
return PNG, nil
default:
return ext, fmt.Errorf("extension: %v error: %w", ext, ErrNotFound)
}
}
使い方
以下にサンプル示します。
- サンプルファイルをオープンし、ファイルサイズチェック
- ファイル拡張子からメディアタイプへ変換
- サンプルファイル読み込みしValidationの実施
import (
"log"
"os"
"github.com/hirac1220/go/go-file-validate/utils/file"
)
func main() {
// ファイルサイズチェック
f, _ := os.Open("./sample/image.jpg") // ファイルオープン
defer func() {
_ = f.Close()
}()
fi, _ := f.Stat()
size, err := file.CheckFileSize(fi.Size()) // ファイルサイズチェック
if err != nil {
log.Println(err)
}
log.Printf("size: %d", size)
// ファイル拡張子からメディアタイプへ変換
ext := file.ExtractExt(fi.Name()) // ファイル拡張子取得
c, err := file.ExtToContentType(ext) // ファイル拡張子からメディアタイプへ変換
if err != nil {
log.Println(err)
}
log.Printf("content type: %s", c)
// ファイルValidation
bytes, _ := os.ReadFile("./sample/image.jpg") // ファイル読み込み
mine, err := file.ValidateFile(&bytes) // ファイルバリデーション
if err != nil {
log.Println(err)
}
log.Printf("mine: %s", mine)
}
実行結果
サンプルファイルに対して実行した結果は以下となります。
$ go run main.go
2022/02/23 17:51:29 size: 2604
2022/02/23 17:51:29 content type: image/jpeg
2022/02/23 17:51:29 mine: image/jpeg
まとめ
今回はGo言語でよく使うファイルのValidation方法などについて解説しました。使用したサンプルはこちらのGitHubレポジトリにあります。
ここまで読んでいただきありがとうございました!