英文:
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 (
"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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论