During the development process of Go language, editor Apple often encounters the need to obtain multipart.File from the multipart.Part object when using the multipart package to process form upload files. However, the multipart package in the standard library does not directly provide a method to obtain multipart.File, but saves the file to disk by default. So, is there a way to bypass this limitation and get multipart.File directly from multipart.Part? Next, we will introduce you to a method to obtain multipart.File from multipart.Part in Go without saving it to disk.
In my go API, I have a previously worked fine by extracting multipart.File
from r.Body
A good function is as follows
file, handler, err := r.FormFile("file")
I use multipart.File
to upload to s3 API using minio client as shown below
err = uploadToMinio(rs, file, fileSize, fileName, guid.String(), userId)
Now that I've added additional form data, I can't seem to achieve this using r.Body anymore. I'm getting an "Error retrieving form file" message as shown in the code below.
Based on this question, I implemented MultipartReader
to get form data from multipart.Part.
part does not have a multipart.File
so I need to implement that part without writing it to disk and reading it again if possible.
This is my code
var err error start := time.Now() const maxUploadSize = 500 * 1024 * 1024 // 500 Mb var requiredByDate FileRequiredDateData mr, err := r.MultipartReader() if err != nil { log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } for { part, err := mr.NextPart() // This is OK, no more parts if err == io.EOF { break } // Some error if err != nil { log.Println("multipart reader other error") http.Error(w, err.Error(), http.StatusInternalServerError) return } log.Println(part.FormName()) if part.FormName() == "data" { log.Println("multipart reader found multipart form name data") decoder := json.NewDecoder(part) err = decoder.Decode(&requiredByDate) if err != nil { log.Println("error in decoding request body data") log.Println(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } if part.FormName() == "file" { file, handler, err := r.FormFile("file") <-- error getting form file here if err != nil { log.Println("error getting form file") log.Println(err.Error()) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusInternalServerError) return } defer file.Close() ---- err = uploadToMinio(rs, file, fileSize, fileName, guid.String(), userId) if err != nil { log.Println(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return }
You are already streaming parts of the form, you cannot call FormFile
now, you must read the file yourself. Use part.Read
to read the bytes of the file, or copy the file, etc. Note that part
implements io.Reader
so you can read from it like a file.
The above is the detailed content of How to get multipart.File from multipart.Part in Go without saving to disk?. For more information, please follow other related articles on the PHP Chinese website!