github.com/gogf/gf@v1.16.9/net/ghttp/ghttp_request_param_file.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package ghttp 8 9 import ( 10 "context" 11 "github.com/gogf/gf/errors/gcode" 12 "github.com/gogf/gf/errors/gerror" 13 "github.com/gogf/gf/internal/intlog" 14 "github.com/gogf/gf/os/gfile" 15 "github.com/gogf/gf/os/gtime" 16 "github.com/gogf/gf/util/grand" 17 "io" 18 "mime/multipart" 19 "strconv" 20 "strings" 21 ) 22 23 // UploadFile wraps the multipart uploading file with more and convenient features. 24 type UploadFile struct { 25 *multipart.FileHeader 26 ctx context.Context 27 } 28 29 // UploadFiles is array type for *UploadFile. 30 type UploadFiles []*UploadFile 31 32 // Save saves the single uploading file to directory path and returns the saved file name. 33 // 34 // The parameter <dirPath> should be a directory path or it returns error. 35 // 36 // Note that it will OVERWRITE the target file if there's already a same name file exist. 37 func (f *UploadFile) Save(dirPath string, randomlyRename ...bool) (filename string, err error) { 38 if f == nil { 39 return "", gerror.NewCode( 40 gcode.CodeMissingParameter, 41 "file is empty, maybe you retrieve it from invalid field name or form enctype", 42 ) 43 } 44 if !gfile.Exists(dirPath) { 45 if err = gfile.Mkdir(dirPath); err != nil { 46 return 47 } 48 } else if !gfile.IsDir(dirPath) { 49 return "", gerror.NewCode(gcode.CodeInvalidParameter, `parameter "dirPath" should be a directory path`) 50 } 51 52 file, err := f.Open() 53 if err != nil { 54 return "", err 55 } 56 defer file.Close() 57 58 name := gfile.Basename(f.Filename) 59 if len(randomlyRename) > 0 && randomlyRename[0] { 60 name = strings.ToLower(strconv.FormatInt(gtime.TimestampNano(), 36) + grand.S(6)) 61 name = name + gfile.Ext(f.Filename) 62 } 63 filePath := gfile.Join(dirPath, name) 64 newFile, err := gfile.Create(filePath) 65 if err != nil { 66 return "", err 67 } 68 defer newFile.Close() 69 intlog.Printf(f.ctx, `save upload file: %s`, filePath) 70 if _, err := io.Copy(newFile, file); err != nil { 71 return "", err 72 } 73 return gfile.Basename(filePath), nil 74 } 75 76 // Save saves all uploading files to specified directory path and returns the saved file names. 77 // 78 // The parameter <dirPath> should be a directory path or it returns error. 79 // 80 // The parameter <randomlyRename> specifies whether randomly renames all the file names. 81 func (fs UploadFiles) Save(dirPath string, randomlyRename ...bool) (filenames []string, err error) { 82 if len(fs) == 0 { 83 return nil, gerror.NewCode( 84 gcode.CodeMissingParameter, 85 "file array is empty, maybe you retrieve it from invalid field name or form enctype", 86 ) 87 } 88 for _, f := range fs { 89 if filename, err := f.Save(dirPath, randomlyRename...); err != nil { 90 return filenames, err 91 } else { 92 filenames = append(filenames, filename) 93 } 94 } 95 return 96 } 97 98 // GetUploadFile retrieves and returns the uploading file with specified form name. 99 // This function is used for retrieving single uploading file object, which is 100 // uploaded using multipart form content type. 101 // 102 // It returns nil if retrieving failed or no form file with given name posted. 103 // 104 // Note that the <name> is the file field name of the multipart form from client. 105 func (r *Request) GetUploadFile(name string) *UploadFile { 106 uploadFiles := r.GetUploadFiles(name) 107 if len(uploadFiles) > 0 { 108 return uploadFiles[0] 109 } 110 return nil 111 } 112 113 // GetUploadFiles retrieves and returns multiple uploading files with specified form name. 114 // This function is used for retrieving multiple uploading file objects, which are 115 // uploaded using multipart form content type. 116 // 117 // It returns nil if retrieving failed or no form file with given name posted. 118 // 119 // Note that the <name> is the file field name of the multipart form from client. 120 func (r *Request) GetUploadFiles(name string) UploadFiles { 121 multipartFiles := r.GetMultipartFiles(name) 122 if len(multipartFiles) > 0 { 123 uploadFiles := make(UploadFiles, len(multipartFiles)) 124 for k, v := range multipartFiles { 125 uploadFiles[k] = &UploadFile{ 126 ctx: r.Context(), 127 FileHeader: v, 128 } 129 } 130 return uploadFiles 131 } 132 return nil 133 }