在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
这个,防止产生内存溢出。原型