go下载
2023-02-18 16:44:57 时间
今天处理GO下载的时候遇到一个问题:如果调用readall去读取response,会造成很大的内存消耗,并且无法获取下载的进度。
直到搜到ioutil.ReadAll(httpResponse.Body) memory consumption,才解决了我的问题。
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
url := "http://dl.360safe.com/setup.exe"
resp, _ := http.Get(url)
filename := "setup.exe"
f, _ := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
n, err := copyBuffer(f, resp.Body, nil)
if err != nil {
fmt.Println(err, n)
}
}
func copyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(io.WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(io.ReaderFrom); ok {
return rt.ReadFrom(src)
}
if buf == nil {
buf = make([]byte, 1024*1024)
}
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er == io.EOF {
break
}
if er != nil {
err = er
break
}
}
return written, err
}
其中copyBuffer的written就可以解决下载进度的问题,并且使用了io.copy打通了读和写的通道,很优雅的解决了问题。
相关文章
- linux系统开mc服务器
- 红队技术-Cobaltstrike之Linux上线
- 权限维持-Linux后门
- 万万没想到,go的数据库操作,也能像php一样溜了
- Typora+PicGo+GitHub实现图片快速上传
- Linux计划任务服务程序
- 2022 如何在 GitHub 上搭建个人网站(github.io)
- 虚拟机安装linux无法访问外网解决办法
- 用过 mongodb 吧, 这三个大坑踩过吗?
- 教你配置windows上的windbg,linux上的lldb,打入clr内部这一篇就够了
- MongoDB 在评论中台的实践
- 使用mongodb作为Quartz.Net下的JobStore实现底层的持久化机制
- mongodb之使用explain和hint性能分析和优化
- mongodb 3.x 之实用新功能窥看[2] ——使用$lookup做多表关联处理
- mongodb 3.x 之实用新功能窥看[1] ——使用TTLIndex做Cache处理
- 双十一来了,别让你的mongodb宕机了
- GO语言开发环境搭建笔记
- PHP判断网络连通
- 开启phpMyAdmin的远程登录
- PHP_cURL初始化和执行方法