猿问

多部分编写器创建表单文件卡住

尝试使用 go 发布多部分/表单数据图像


图像文件从请求客户端接收,并且已另存为多部分。文件


这是我的代码


func postImage(file multipart.File, url string, filename string) (*http.Response, error) {

    r, w := io.Pipe()

    defer w.Close()

    m := multipart.NewWriter(w)

    defer m.Close()


    errchan := make(chan error)

    defer close(errchan)


    go func() {

        part, err := m.CreateFormFile("file", filename)

        log.Println(err)

        if err != nil {

            errchan <- err

            return

        }


        if _, err := io.Copy(part, file); err != nil {

            errchan <- err

            return

        }

    }()


    merr := <-errchan

    if merr != nil {

        return nil, merr

    }


    resp, err := http.Post(url, m.FormDataContentType(), r)

    if err != nil {

        return nil, err

    }

    defer resp.Body.Close()


    return resp, err

}

当我尝试使用它时,它卡在永远不会返回任何东西part, err := m.CreateFormFile("file", filename)


任何解决方案?


慕勒3428872
浏览 60回答 1
1回答

湖上湖

使用管道错误将错误传播回主 goroutine。关闭管道的写入端,以防止客户端在读取时永久阻塞。关闭管道的读取侧,以确保 goroutine 退出。func postImage(file multipart.File, url string, filename string) (*http.Response, error) {&nbsp; &nbsp; r, w := io.Pipe()&nbsp; &nbsp; // Close the read side of the pipe to ensure that&nbsp; &nbsp; // the goroutine exits in the case where http.Post&nbsp; &nbsp; // does not read all of the request body.&nbsp; &nbsp; defer r.Close()&nbsp; &nbsp; m := multipart.NewWriter(w)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; part, err := m.CreateFormFile("file", filename)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // The error is returned from read on the pipe.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; w.CloseWithError(err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if _, err := io.Copy(part, file); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // The error is returned from read on the pipe.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; w.CloseWithError(err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // The http.Post function reads the pipe until&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // an error or EOF. Close to return an EOF to&nbsp; &nbsp; &nbsp; &nbsp; // http.Post.&nbsp; &nbsp; &nbsp; &nbsp; w.Close()&nbsp; &nbsp; }()&nbsp; &nbsp; resp, err := http.Post(url, m.FormDataContentType(), r)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return nil, err&nbsp; &nbsp; }&nbsp; &nbsp; defer resp.Body.Close()&nbsp; &nbsp; return resp, err}
随时随地看视频慕课网APP

相关分类

Go
我要回答