viper-app/pkg/file/file_util.go

140 lines
2.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package file
import (
"btdp-agent-admin/pkg/md5"
"errors"
"go.uber.org/zap"
"io"
"mime/multipart"
os "os"
"path/filepath"
"strings"
)
func Save(r io.Reader, dst string) (err error) {
var (
fp string
out io.WriteCloser
)
fp = filepath.Dir(dst)
err = DirCheck(fp)
out, err = os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, r)
return
}
// MD5 计算文件 md5 值
func MD5(file string) (string, error) {
f, err := os.Open(file)
if err != nil {
return "", err
}
info, err := f.Stat()
if err != nil {
return "", err
}
size := info.Size()
return md5.Sum(f, size, BlockSize, ChunkSize)
}
func MultipartMD5(fh *multipart.FileHeader) (string, error) {
f, err := fh.Open()
if err != nil {
return "", err
}
size := fh.Size
return md5.Sum(f, size, BlockSize, ChunkSize)
}
const (
BlockSize = 1 << 10
ChunkSize = BlockSize << 2
)
var (
ErrorIsNotDir = errors.New("path is not dir. ")
)
func DirCheck(dir string) (err error) {
var fi os.FileInfo
if fi, err = os.Stat(dir); err != nil {
if !os.IsExist(err) || os.IsNotExist(err) {
return DirMk(dir)
}
}
if !fi.IsDir() {
err = ErrorIsNotDir
}
return
}
func DirMk(dir string) error {
return os.MkdirAll(dir, 0755)
}
const MaxScanDeep = 20
var maxDeepError = errors.New("scanMaxDeep")
func IsScanMaxDeep(err error) bool {
return errors.Is(err, maxDeepError)
}
// DirScan 扫描目录on err skip
func DirScan(dir string, h func(dir string, info os.FileInfo)) error {
return dirScan(dir, h, 0)
}
func dirScanIgnore(name string) bool {
return strings.HasPrefix(name, ".") ||
strings.Contains(strings.ToLower(name), "readme")
}
func dirScan(dir string, h func(dir string, info os.FileInfo), deep int) error {
if deep > MaxScanDeep {
return maxDeepError
}
dirs, err := os.ReadDir(dir)
if err != nil {
return err
}
var (
info os.FileInfo
nextDir string
)
for _, entry := range dirs {
info, err = entry.Info()
if err != nil {
zap.L().Warn("scan err", zap.String("name", entry.Name()), zap.Error(err))
continue
}
if dirScanIgnore(info.Name()) {
continue
}
h(dir, info)
if entry.IsDir() {
nextDir = filepath.Join(dir, info.Name())
if err = dirScan(nextDir, h, deep+1); err != nil {
zap.L().Warn("scan err", zap.String("dirname", nextDir), zap.Error(err))
}
}
}
return err
}