在golang中,若是咱們要下載一個文件,最簡單的就是先用http.get()方法建立一個遠程的請求後,後面可以使用ioutil.WriteFile()等將請求內容直接寫到文件中。golang
func DownFile() { url :="http://wx.qlogo.cn/Vaz7vE1/64" resp ,err := http.Get(url) if err != nil { fmt.Fprint(os.Stderr ,"get url error" , err) } defer resp.Body.Close() data ,err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } _ =ioutil.WriteFile("/tmp/icon_wx.png", data, 0755) }
可是你會發現,上面的操做方式會有一個小問題,那就是下載小文件還行,若是是大的文件的話,可能會出現內存不足的問題,由於它是須要先把請求內容所有讀取到內存中,而後再寫入到文件中的。url
那若是要下載大文件或者複製大文件,應該怎麼辦呢? 其實,Golang中就提供了 io.copy
方法,它就是在文件指針之間直接複製的,不用全讀入內存,可解決這樣的問題。指針
咱們先看下原型聲明code
func Copy(dst Writer, src Reader) (written int64, err error) { return copyBuffer(dst, src, nil) } func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) { .... if buf == nil { size := 32 * 1024 if l, ok := src.(*LimitedReader); ok && int64(size) > l.N { if l.N < 1 { size = 1 } else { size = int(l.N) } } buf = make([]byte, size) }
它是將源複製到目標,而且是按默認的緩衝區32k循環操做的,不會將內容一次性全寫入內存中,這樣就能解決大文件的問題。內存
咱們再用 io.copy
來實現一下吧。get
func DownFile() { url :="http://wx.qlogo.cn/Vaz7vE1/64" resp ,err := http.Get(url) if err != nil { fmt.Fprint(os.Stderr ,"get url error" , err) } defer resp.Body.Close() out, err := os.Create("/tmp/icon_wx_2.png") wt :=bufio.NewWriter(out) defer out.Close() n, err :=io.Copy(wt, resp.Body) fmt.Println("write" , n) if err != nil { panic(err) } wt.Flush() }
同理,若是咱們要複製大文件也能夠用 io.copy
這個,防止產生內存溢出。原型