net/http 下载

在golang中,如果我们要下载一个文件,最简单的就是先用http.get()方法创建一个远程的请求后,后面可使用ioutil.WriteFile()等将请求内容直接写到文件中。

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)
}

但是你会发现,上面的操作方式会有一个小问题,那就是下载小文件还行,如果是大的文件的话,可能会出现内存不足的问题,因为它是需要先把请求内容全部读取到内存中,然后再写入到文件中的。

那如果要下载大文件或者复制大文件,应该怎么办呢? 其实,Golang中就提供了 io.copy方法,它就是在文件指针之间直接复制的,不用全读入内存,可解决这样的问题。

io.copy

我们先看下原型声明

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 来实现一下吧。

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

最新文章

  1. Gulp:自动化构建工具
  2. Android之JSON解析
  3. Windows Azure Active Directory (1) 前言 - 基于声明的验证和授权
  4. 烂泥:更换ESXI5.0管理网卡及管理IP地址
  5. 访问者(Visitor)模式
  6. 【iCore3 双核心板】例程八:定时器PWM实验——呼吸灯
  7. DOM解析XML练习
  8. Android Studio--学习系列(1)
  9. VC++代码的汇编分析(一)
  10. 关于数组和List之间相互转换的方法
  11. 定时器NSTimer的用法
  12. 关于我的FGC的OAuth2.0认证。
  13. ssh免密码登陆远程服务器
  14. 201521123035《Java程序设计》第七周学习总结
  15. macOS安装beego的使用bee命令出现killed:9 解决办法
  16. JAVA设计模式---迭代器模式
  17. TCP-IP详解笔记5
  18. mysql 5.5数据导入5.7 Failed - Error on Table user - 1067 - Invalid default value for &#39;CREATE_date&#39;
  19. css的再深入7(更新中&#183;&#183;&#183;)
  20. Ionic下的Jpush消息推送与内容显示

热门文章

  1. 题解【POJ2955】Brackets
  2. django-cors-headers
  3. Laravel Vuejs 实战:开发知乎 (5)设计问题表
  4. JDK-13下载安装及环境变量配置
  5. [AST Babel Plugin] Transform code, add line:column number for console log
  6. JS高级---实例对象使用属性和方法层层的搜索 (实例对象--&gt;原型对象--&gt;报错)
  7. casperJs的安装
  8. EVE上传Dynamips、IOL和QEMU镜像
  9. [1/100]Python安装
  10. IoT生态不完善、与智能电视区别不大,荣耀智慧屏概念大于实际