Home  >  Article  >  Backend Development  >  How to get multipart.File from multipart.Part in Go without saving to disk?

How to get multipart.File from multipart.Part in Go without saving to disk?

WBOY
WBOYforward
2024-02-08 22:03:09634browse

How to get multipart.File from multipart.Part in Go without saving to disk?

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.

Question content

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.

The

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
        }

Workaround

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete