如何在 Go 中“桥接”作者和读者

mar*_*ark 2 go

我通常会在 Golang 中找到 Reader 和 Writer,但我遇到了一个对我来说很陌生的情况。

我正在使用“golang.org/x/net/html”渲染。它输出到 Writer w。我想使用该输出并从中创建一个新请求。NewRequest 使用 Reader r。

err := html.Render(w, msg)
...
req, err := http.NewRequest("Post", url, r)
io.Copy(w, r)
Run Code Online (Sandbox Code Playgroud)

我的问题是“使用 w 和 r 绑定两个调用的最佳/理想解决方案是什么?”。我在网上找不到类似情况的示例。我正在考虑创建 Reader 和 Writer 并在它们上使用 io.Copy(w, r) 。我不确定,因为对于显然经常使用的东西来说,这似乎有点复杂。

Cer*_*món 6

一个简单的方法是使用bytes.Buffer

var buf bytes.Buffer
err := html.Render(&buf, msg)
...
req, err := http.NewRequest("POST", url, &buf)
Run Code Online (Sandbox Code Playgroud)

这会将整个请求缓冲在内存中。另一种不缓冲内存中所有内容的方法是使用io.Pipe。这种方法比较复杂,因为它在程序中引入了并发性。此外,在渲染中检测到可能的错误之前,http 客户端开始将请求写入线路。

r, w := io.Pipe()
go func() {
    w.CloseWithError(html.Render(w, msg))
}()
req, err := http.NewRequest("POST", url, r)
Run Code Online (Sandbox Code Playgroud)