在我的go API中,我有一个函数,它以前工作得很好,可以像这样从r.Body中提取multipart.File

file, handler, err := r.FormFile("file") 

我使用multipart.File通过Minio客户端上传到S3API,如下所示

err = uploadToMinio(rs, file, fileSize, fileName, guid.String(), userId)

现在我已经添加了额外的表单数据,似乎不能再为此使用r.Body.我收到"获取表单文件时出错",如下面的代码所示.

this question之后,我实现了一个MultipartReader来从多方获取表单数据.

Part没有multipart.File,所以如果可能的话,我需要在不将Part写入磁盘并再次读取的情况下达到该值.

以下是我的代码

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
        }

推荐答案

您已经在传输表格的各个部分,您现在不能拨打FormFile,您必须自己阅读文件.使用part.Read来读取文件的字节,或者复制它,等等.请注意,part实现了io.Reader,因此您可以像读取文件一样读取它.

Go相关问答推荐

语法-for循环中的initit陈述是否允许分配?

使用恶意软件 scanner (ClamAV)时的Google云存储桶上传文件验证

在Go中根据命名空间/字符串生成UUID

Go中的net.SplitHostPort(r.RemoteAddr)安全性

CURL和Postman HTTP POST工作,但Golang请求失败,状态为400

如何在出现错误时停止从通道读取?

转到 bufio.Writer、gzip.Writer 并上传到内存中的 AWS S3

如何根据地址和大小打印字符串

如何将任何类型的数据值传递到 Golang 中的 GRPC Protobuf struct ?

AWS Lambda 中的 Websocket URL 超时达到错误

linter 警告:返回值被忽略

Gremlin-Go:树步骤不可序列化

如何匹配两次出现的相同但随机字符串之间的字符

Go 信号处理程序不处理终端窗口关闭

在 GORM 中,如何在特定时区配置 autoCreateTime 和 autoUpdateTime?

跟踪长时间运行的任务的进度 - 正确的方法

如何正确判断 io.Reader 是否为零?

Golang 有类似 C++ 的 decltype 的东西吗?

如何使用 httputil.ReverseProxy 设置 X-Forwarded-For

Go 错误:cannot use generic type without instantiation