上载大文件 - 错误 x 字节的虚拟分配失败,errno=1455 致命错误:内存不足

我有10GB的大文件,我正在尝试通过Postman在Go中上传多部分/表单数据。由于我不太了解文件上传在Go中的工作原理,因此我在YouTube上找到了教程。


文件上传适用于较小的文件,但在较大的文件上总是崩溃,并显示消息:“运行时:9193373696字节的虚拟Alloc失败,errno = 1455致命错误:内存不足”。以下是我尝试编写的代码:


    err := r.ParseMultipartForm(500 << 20)

    if err != nil {

        fmt.Fprintln(w, err)

    }


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


    if err != nil {

        fmt.Fprintln(w, err)

    }


    fmt.Fprintln(w, handler.Filename)

    fmt.Fprintln(w, handler.Size)

    fmt.Fprintln(w, handler.Header.Get("Content-type"))


    defer file.Close()


    saveLocation := "C:\\Users\\Pc\\go\\src\\github.com\\test\\uptest"

    tempFile, err := ioutil.TempFile(saveLocation, "upload")


    if err != nil {

        fmt.Fprintln(w, err)

    }


    defer tempFile.Close()


    fileBytes, err := ioutil.ReadAll(file)

    if err != nil {

        fmt.Fprintln(w, err)

    }

    tempFile.Write(fileBytes)


眼眸繁星
浏览 235回答 1
1回答

FFIVE

使用将要求您提供最大内存分配以临时存储上传的文件。如果您的文件大小很大(并且大于您分配的内存量),那么这对您的内存资源来说是个坏消息。ParseMultipartForm()来自 文档:解析多部分Form将请求正文解析为多部分/表单数据。对整个请求正文进行解析,其文件部分的内存字节最多最大存储在内存中,其余部分存储在磁盘上的临时文件中。如有必要,解析多部分窗体调用解析窗体。在对解析多部分窗体进行一次调用后,后续调用将不起作用。根据您的错误消息,我们可以判断出问题的根本原因是由于上传的文件大于您分配的内存,即 。500 << 20为了处理大文件上传,我建议看看。MultipartReader()从 doc:多部分读取器返回 MIME 多部分读取器,如果这是多部分/表单数据或多部分/混合 POST 请求,否则返回 nil 和错误。使用此函数而不是解析多部分窗体将请求正文作为流进行处理。这是一种更快的方法,并且不会消耗太多资源,这是因为我们将具有使用直接将正文(即流数据)存储到目标文件的优点,而不是首先将其写入临时存储中。io.Copy()的简单用法示例:MultipartReader()reader, err := r.MultipartReader()if err != nil {&nbsp; &nbsp; http.Error(w, err.Error(), http.StatusInternalServerError)&nbsp; &nbsp; return}for {&nbsp; &nbsp; part, err := reader.NextPart()&nbsp; &nbsp; if err == io.EOF {&nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(part.FileName()) // prints file name&nbsp; &nbsp; fmt.Println(part.FormName()) // prints form key, in yor case it's "file"&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; saveLocation := "C:\\Users\\Pc\\go\\src\\github.com\\test\\uptest"&nbsp; &nbsp; dst, err := os.Create(saveLocation)&nbsp; &nbsp; if dst != nil {&nbsp; &nbsp; &nbsp; &nbsp; defer dst.Close()&nbsp; &nbsp; }&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; http.Error(w, err.Error(), http.StatusInternalServerError)&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; if _, err := io.Copy(dst, part); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; http.Error(w, err.Error(), http.StatusInternalServerError)&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }}参考编号: https://pkg.go.dev/net/http#Request.ParseMultipartForm
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go