123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package file
- import (
- "crypto/md5"
- "encoding/hex"
- "icloudapp.cn/tools/util"
- "io"
- "mime/multipart"
- "os"
- "path"
- "strconv"
- "strings"
- "time"
- )
- type Upload struct {
- Path string
- Allowed map[string]bool
- HasHash bool
- }
- type FileWithErr struct {
- Err error
- FileInfo *File
- }
- type File struct {
-
- Name string `json:"name"`
-
- File string `json:"file"`
- Basename string `json:"basename"`
-
- Size int64 `json:"size"`
-
- Hash string `json:"hash"`
-
- Mine string `json:"mine"`
- }
- func NewUpload(dir string) *Upload {
- return &Upload{
- Path: dir,
- }
- }
- func (u *Upload) SetHasHash(hashash bool) {
- u.HasHash = hashash
- }
- func (u *Upload) SetUploadPath(dir string) {
- u.Path = dir
- }
- func (u *Upload) SetAllowed(allowed map[string]bool) {
- u.Allowed = allowed
- }
- func (u *Upload) AppendAllow(ext string) {
- u.Allowed[ext] = true
- }
- func (u *Upload) Single(file multipart.FileHeader) (*File, error) {
- res := &File{}
- extName := strings.ToLower(path.Ext(file.Filename))
- if _, ok := u.Allowed[extName]; !ok {
- return res, util.NewError("不允许的上传类型")
- }
- res.Name = file.Filename
- res.Size = file.Size
- res.Mine = file.Header.Get("Content-Type")
- if !IsDir(u.Path) {
- if err := os.MkdirAll(u.Path, 0750); err != nil {
- return nil, util.NewError("目录创建失败", u.Path)
- }
- }
- fileUnixName := strconv.FormatInt(time.Now().UnixNano(), 10)
- res.Basename = fileUnixName + extName
- savePath := path.Join(u.Path, res.Basename)
- res.File = savePath
- src, err := file.Open()
- if err != nil {
- return nil, util.NewError("文件打开失败:", err.Error())
- }
- defer src.Close()
- out, err := os.Create(savePath)
- if err != nil {
- return nil, util.NewError("文件创建失败:", err.Error())
- }
- defer out.Close()
- if u.HasHash {
- res.Hash = u.FileHash(savePath)
- }
- _, err = io.Copy(out, src)
- return res, nil
- }
- func (u *Upload) Multiple(files []multipart.FileHeader) ([]*FileWithErr, error) {
- var res []*FileWithErr
- for key, file := range files {
- uploaded, err := u.Single(file)
- res[key] = &FileWithErr{Err: err, FileInfo: uploaded}
- }
- return res, nil
- }
- func (u *Upload) FileHash(path string) string {
- file, _ := os.Open(path)
- m := md5.New()
- _, err := io.Copy(m, file)
- if err == nil {
- hash := m.Sum(nil)
- return hex.EncodeToString(hash)
- }
- return ""
- }
|