登录
首页 >  Golang >  Go问答

使用 io.Pipe 从 exec.command 获取输出以进行 http post

来源:stackoverflow

时间:2024-04-09 08:03:26 200浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《使用 io.Pipe 从 exec.command 获取输出以进行 http post》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

正在阅读如何使用 io.pipe 来减少分配(无需将 cmd.stdout 分配给 bytes.buffer)。我无法让以下内容工作,并且非常感谢我如何使用 io.pipe 从 exec.command 获取输出以发出 http mutliform post 请求。

func main() {
    cmd := exec.command("convert", "test.png", "-resize" "30x30", "png:-")
    bodyreader, bodywriter := io.pipe()
    cmd.stdout = bodywriter
    formwriter := multipart.newwriter(bodywriter)
    go func() {
        cmd.run()
        partwriter, err := formwriter.createformfile("file", "file")
        if err != nil {
            fmt.println("form writer create error")
            return
        }
        _, err = io.copy(partwriter, bodyreader)
        if err != nil {
            fmt.println("io copy error")
            return
        }
        formwriter.close()
        bodywriter.close()
    }()

    url := "http://example.com/upload"
    req, _ := http.newrequest(http.methodpost, url, bodyreader)
    req.header.set("content-type", formwriter.formdatacontenttype())
    resp, err := http.defaultclient.do(req)
    if err != nil {
        fmt.println("htttp do error")
        return
    }
    fmt.println(resp.statuscode)
    respbody, err := ioutil.readall(resp.body)
    if err != nil {
        fmt.println("read error")
        return
    }
    fmt.println("result:", string(respbody))
}

使用调试工具,它只是挂在 resp, err := http.defaultclient.do(req) 并最终得到以下输出。

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x1218c3b]

goroutine 1 [running]:
main.main()

正确答案


您需要为 multipart.writer 添加另一个 pipe

func main() {
    cmd := exec.Command("convert", "./test.jpg", "-resize", "30x30", "jpg:-")
    bodyReader, bodyWriter := io.Pipe()
    cmd.Stdout = bodyWriter
    cmd.Stderr = os.Stderr
    formReader, formWriter := io.Pipe()
    multiWriter := multipart.NewWriter(formWriter)

    go func() {
        if err := cmd.Run(); err != nil {
            bodyWriter.CloseWithError(err)
        } else {
            bodyWriter.Close()
        }
    }()

    go func() {
        partWriter, err := multiWriter.CreateFormFile("file", "file")
        if err != nil {
            formWriter.CloseWithError(err)
            return
        }

        _, err = io.Copy(partWriter, bodyReader)
        if err != nil {
            formWriter.CloseWithError(err)
            return
        }

        multiWriter.Close()
        formWriter.Close()
    }()

    url := "http://example.com/upload"
    req, _ := http.NewRequest(http.MethodPost, url, formReader)
    fmt.Println(multiWriter.FormDataContentType())
    req.Header.Set("Content-Type", multiWriter.FormDataContentType())
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println("htttp do error")
        return
    }
    fmt.Println(resp.StatusCode)
    respBody, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("read error")
        return
    }
    fmt.Println("Result:", string(respBody))
}

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《使用 io.Pipe 从 exec.command 获取输出以进行 http post》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>