在Go语言中,将io.ReadCloser流式传输到文件的最有效方法是什么?

huangapple go评论72阅读模式
英文:

Most efficient way in Go to stream io.ReadCloser to a file?

问题

给定一个io.ReadCloser,例如来自HTTP请求的响应,最高效的方式是什么,既要考虑内存开销,又要考虑代码的可读性,将响应流式传输到文件中?

英文:

Given an io.ReadCloser, from the response of an HTTP request for example, what is the most efficient way both in memory overhead and code readability to stream the response to a File?

答案1

得分: 21

io.Copy在代码方面无疑是最高效的;你只需要:

outFile, err := os.Create(filename)
// 处理错误
defer outFile.Close()
_, err = io.Copy(outFile, res.Body)
// 处理错误

从CPU和内存的角度来看,它也很可能非常高效。如果你想的话,可以查看io.Copy的实现;假设body没有实现WriteTo,文件没有实现ReadFrom(快速浏览显示它们没有),Copy将一次复制最多32kB的数据块。更大的数据块可能会使用更少的CPU,但更多的内存;他们选择的值似乎是一个很好的折衷。

英文:

io.Copy is undoubtedly the most efficient in terms of code; you only need to

<!-- lang: go -->

outFile, err := os.Create(filename)
// handle err
defer outFile.Close()
_, err = io.Copy(outFile, res.Body)
// handle err

it's also likely to be pretty efficient in terms of CPU and memory as well. You can peek at the implementation of io.Copy if you want; assuming that the body doesn't implement WriteTo and the file doesn't implement ReadFrom (a quick glance says that they don't), Copy will copy chunks of up to 32kB at a time. A bigger chunk would probably use a bit less CPU but more memory; the value they picked seems like a good tradeoff.

答案2

得分: 0

另一个选项是File.ReadFrom

package main

import (
   "net/http"
   "os"
)

func main() {
   r, e := http.Get("https://stackoverflow.com")
   if e != nil {
      panic(e)
   }
   defer r.Body.Close()
   f, e := os.Create("index.html")
   if e != nil {
      panic(e)
   }
   defer f.Close()
   f.ReadFrom(r.Body)
}

https://golang.org/pkg/os#File.ReadFrom

英文:

Another option is File.ReadFrom:

package main

import (
   &quot;net/http&quot;
   &quot;os&quot;
)

func main() {
   r, e := http.Get(&quot;https://stackoverflow.com&quot;)
   if e != nil {
      panic(e)
   }
   defer r.Body.Close()
   f, e := os.Create(&quot;index.html&quot;)
   if e != nil {
      panic(e)
   }
   defer f.Close()
   f.ReadFrom(r.Body)
}

https://golang.org/pkg/os#File.ReadFrom

huangapple
  • 本文由 发表于 2015年8月12日 10:06:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/31954899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定