golang的io.copy使用
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 这个,防止产生内存溢出。
golang的io.copy使用的更多相关文章
- Golang学习 - io 包
------------------------------------------------------------ 先说一下接口,Go 语言中的接口很简单,在 Go 语言的 io 包中有这样一个 ...
- Golang文件IO 一
Golang文件IO 一 文件IO编程最基本.最常用的就属读写文件操作了.ioutil包实现了一些IO实用功能,其中就包括非常简捷.好用的文件读取功能. ioutil包有7个函数1个变量: var D ...
- 关于golang中IO相关的Buffer类浅析
io重要的接口 在介绍buffer之前,先来认识两个重要的接口,如下边所示: type Reader interface { Read(p []byte) (n int, err error) } t ...
- Golang学习 - io/ioutil 包
------------------------------------------------------------ // Discard 是一个 io.Writer 接口,调用它的 Write ...
- golang io中io.go解读
目录 1. 整体大纲 2. 接口 读 写 关闭 寻址 3. 函数 读 写 复制 4. 结构体 SectionReader LimitedReader teeReader 5. 备注 根据golang ...
- golang IO streaming
IO Streaming Streaming IO in Go,引用此文,略有修改 io.Reader和io.Writer io.Reader接口定义了从传输缓存读取数据 type Reader in ...
- GoLang之网络
GoLang之网络 Go语言标准库里提供的net包,支持基于IP层.TCP/UDP层及更高层面(如HTTP.FTP.SMTP)的网络操作,其中用于IP层的称为Raw Socket. net包的Dial ...
- golang文件上传和下载
[代码]golang 实现的文件服务(包括上传,下载的server端和client端) (2013-09-20 02:03:52) 转载▼ 标签: golang go 文件服务器 it 分类: GO相 ...
- [转]50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs
http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/ 50 Shades of Go: Traps, Gotc ...
随机推荐
- pycharm的一些快捷键[转]
编辑类: Ctrl + Space 基本的代码完成(类.方法.属性)Ctrl + Alt + Space 类名完成Ctrl + Shift + Enter 语句完成Ctrl + P 参数信息(在方法中 ...
- python中给函数传参是传值还是传引用
首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...
- centos 7 添加swap
[root@lab01 /]# cd / [root@lab01 /]# + records in + records out bytes ( MB/s [root@lab01 /]# free -m ...
- CRPR/CPPR
S CRPR clock reconvergence pessimism removal C CPPR clock path pessimism removal 剔除公共clock path上的悲 ...
- ARM架构Linux环境安装python2.7.9
1.下载python # wget https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz 2.解压.编译安装 # tar -zxvf Pyt ...
- 6_3 矩阵链乘(UVa424)<用栈实现简单的表达式解析>
假设你必须做A*B*C*D*E的运算,在这里A,B,C,D,E都是矩阵(matrix).由于矩阵相乘具有连接性(associative),所以相乘的顺序可以是任意的.然而所需要的基本乘法数却与不尽相同 ...
- Error: EACCES: permission denied, open '/Users/qinmengjiao/WebstormProjects/m-kbs-app/.babelrc
表示没有访问这个文件的权限 执行命令 sudo chown -R $(whoami) ~/WebstormProjects/m-kbs-app/.babelrc 就可以解决上面的问题 以下是chown ...
- JenKins docker 集群
//tag 桉树有时间来搞 **阿斯蒂 啊 阿斯蒂
- 【PAT甲级】1088 Rational Arithmetic (20 分)
题意: 输入两个分数(分子分母各为一个整数中间用'/'分隔),输出它们的四则运算表达式.小数需要用"("和")"括起来,分母为0的话输出"Inf&qu ...
- layui 延时加载
//延时关闭当前页面,并刷新父页面layer.msg('提交成功',{time: 1800},function () { parent.layer.close(index); window.paren ...