douliao1911
2016-01-18 12:56
浏览 580
已采纳

如何将io.ReadCloser流式传输到golang中的http.ResponseWriter?

I have a client which makes a request to download a file, the web server forwards this request on to the resource server that actually holds the file. The *http.Response back from the resource server has the Body io.ReaderCloser streaming the file contents from the resource server. But I'm then at the point where I want to start writing that into the original http.ResponseWriter that came from the client. Looking at the http.ResponseWriter interface it only contains a Write method which takes a slice of bytes, which makes me think that the only way to get the file contents back to the client is to read the Body io.ReaderCloser into a buffer and then put that into the http.ResponseWriter's Write method. which I dont want to do since that is hugely inefficient and it would be much better to stream it through my web server. Is this possible?

here is some code to illustrate:

getFile() *http.Response {
    //make a request to resource server and return the response object
}

// handle request from client
http.HandleFunc("/getFile", func(w http.ResponseWriter, r *http.Request){
    res := getFile()
    //how can I stream res.Body into w without buffering ?
})

图片转代码服务由CSDN问答提供 功能建议

我有一个客户端请求下载文件,Web服务器将此请求转发到资源服务器上 实际保存文件。 从资源服务器返回的* http.Response具有Body io.ReaderCloser,流式传输来自资源服务器的文件内容。 但是,现在我想开始将其写入来自客户端的原始http.ResponseWriter中。 查看http.ResponseWriter接口,它仅包含一个使用一片字节的Write方法,这使我认为将文件内容返回给客户端的唯一方法是将Body io.ReaderCloser读入缓冲区,然后 将其放入http.ResponseWriter的Write方法。 我不想这样做,因为那是非常低效的,并且最好通过我的Web服务器将其流式传输。

下面是一些代码来说明:

  getFile()* http.Response {
 //创建一个 请求到资源服务器并返回响应对象
} 
 
 //处理来自客户端的请求
http.HandleFunc(“ / getFile”,func(w http.ResponseWriter,r * http.Request){
 res:  = getFile()
 //如何在不缓冲的情况下将res.Body传输到w中?
})
   
 
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongyou2714 2016-01-18 12:59
    已采纳

    You can use io.Copy() which does exactly this.

    Copy copies from src to dst until either EOF is reached on src or an error occurs. It returns the number of bytes copied and the first error encountered while copying, if any.

    n, err := io.Copy(w, res.Body)
    // check err
    

    Also note that Copy() will not return io.EOF but nil because if it can "copy" everything until src reports io.EOF, that is not considered an error.

    已采纳该答案
    打赏 评论