Golang 使用http Client下载文件的实现方法
本篇文章向大家介绍《Golang 使用http Client下载文件的实现方法》,主要包括HTTP、client、下载文件,具有一定的参考价值,需要的朋友可以参考一下。
之前使用beego的http库的时候,有的情况需要下载文件。beego是能实现,但就是有点问题:不支持回调,没法显示下载速度,这在日常开发中是不可忍受的。
看了下beego的实现主要是使用了io.copy函数,于是就深入的看了下实现原理,发现挺简单的,于是就根据io.copy原理实现的一个简单的下载器
//定义要下载的文件 var durl = "https://dl.google.com/go/go1.10.3.darwin-amd64.pkg"; //解析url uri, err := url.ParseRequestURI(durl) if err != nil { panic("网址错误") }
正常的一个流程先看看Url有没有错误
filename := path.Base(uri.Path) log.Println("[*] Filename " + filename)
使用path.Base取出url的文件名称,这里有个可能会出现bug的地方:如果这个网址是302跳转过去的话是没法取出跳转过后的文件名称。
取文件名称这步可以再发送http请求的时候 client.CheckRedirect定义一个函数取出文件名次即可。
client := http.DefaultClient; client.Timeout = time.Second * 60 //设置超时时间 resp, err := client.Get(durl)
创建一个httpClient,另外这个客户端的Timeout是设置读取数据的时候多少时间算超时。
我这里比较推崇用Do方法传递一个Reqeust过去,应为有的url需要校验http头之类的,你问我为啥不用一个字懒。
raw := resp.Body defer raw.Close() reader := bufio.NewReaderSize(raw, 1024*32);
其实说实话不太清楚bufio能不能真正的加快htpp读取速度,没有做过跟不用bufio的对比。但是为了心理上的安心就加上去了
file, err := os.Create(filename) if err != nil { panic(err) } writer := bufio.NewWriter(file)
同上也不太确定bufio能对文件写入增加多少速度
buff := make([]byte, 32*1024) written := 0 go func() { for { nr, er := reader.Read(buff) if nr > 0 { nw, ew := writer.Write(buff[0:nr]) if nw > 0 { written += nw } if ew != nil { err = ew break } if nr != nw { err = io.ErrShortWrite break } } if er != nil { if er != io.EOF { err = er } break } } if err != nil { panic(err) } }()
这个源码是我直接复制io.copyBuffer函数的只是做了一些简单的修改理解大概意思就行
//间隔时间 spaceTime := time.Second * 1 //定时器 ticker := time.NewTicker(spaceTime) //上次读取数据大小 lastWtn := 0 stop := false for { select { case这段代码堵塞住程序,然后定时器按照间隔时间来计算速度。这里可能会出现bug的地方就是在间隔时间内没有读取到数据的时候回直接跳出循环。现在这个时间点非常困,写个blog已经困的要死了以后有空把这个bug解决了吧
func bytesToSize(length int) string { var k = 1024 // or 1024 var sizes = []string{"Bytes", "KB", "MB", "GB", "TB"} if length == 0 { return "0 Bytes" } i := math.Floor(math.Log(float64(length)) / math.Log(float64(k))) r := float64(length) / math.Pow(float64(k), i) return strconv.FormatFloat(r, 'f', 3, 64) + " " + sizes[int(i)] }这个函数是我从我个人的php项目中转换过来的
2018/08/17 00:24:50 [*] Filename go1.10.3.darwin-amd64.pkg 2018/08/17 00:24:51 [*] Speed 9.000 MB / 1s 2018/08/17 00:24:52 [*] Speed 11.125 MB / 1s 2018/08/17 00:24:53 [*] Speed 11.125 MB / 1s 2018/08/17 00:24:54 [*] Speed 10.562 MB / 1s 2018/08/17 00:24:55 [*] Speed 11.187 MB / 1s 2018/08/17 00:24:56 [*] Speed 11.109 MB / 1s 2018/08/17 00:24:57 [*] Speed 11.109 MB / 1s 2018/08/17 00:24:58 [*] Speed 11.141 MB / 1s 2018/08/17 00:24:59 [*] Speed 11.172 MB / 1s 2018/08/17 00:25:00 [*] Speed 11.141 MB / 1s 2018/08/17 00:25:01 [*] Speed 8.453 MB / 1s 2018/08/17 00:25:02 [*] Speed 6.385 MB / 1s 2018/08/17 00:25:03 [*] Speed 0 Bytes / 1s这是最终的运行结果,然后我再把全部的源码放在下面就去睡了。
package main import ( "net/http" "log" "time" "net/url" "path" "os" "io" "bufio" "math" "strconv" ) var durl = "https://dl.google.com/go/go1.10.3.darwin-amd64.pkg"; func main() { uri, err := url.ParseRequestURI(durl) if err != nil { panic("网址错误") } filename := path.Base(uri.Path) log.Println("[*] Filename " + filename) client := http.DefaultClient; client.Timeout = time.Second * 60 //设置超时时间 resp, err := client.Get(durl) if err != nil { panic(err) } if resp.ContentLength 0 { nw, ew := writer.Write(buff[0:nr]) if nw > 0 { written += nw } if ew != nil { err = ew break } if nr != nw { err = io.ErrShortWrite break } } if er != nil { if er != io.EOF { err = er } break } } if err != nil { panic(err) } }() spaceTime := time.Second * 1 ticker := time.NewTicker(spaceTime) lastWtn := 0 stop := false for { select { case以上这篇Golang 使用http Client下载文件的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持golang学习网。
文中关于golang的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Golang 使用http Client下载文件的实现方法》文章吧,也可关注golang学习网公众号了解相关技术文章。

- 上一篇
- golang 检查网络状态是否正常的方法

- 下一篇
- golang http连接复用方法
-
- 潇洒的黑猫
- 太详细了,码住,感谢up主的这篇文章,我会继续支持!
- 2023-02-28 10:45:16
-
- 虚心的香水
- 这篇文章太及时了,很详细,很有用,已收藏,关注作者大大了!希望作者大大能多写Golang相关的文章。
- 2023-02-24 02:35:07
-
- 要减肥的老虎
- 很好,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者分享文章内容!
- 2023-02-19 07:19:58
-
- 怕孤独的薯片
- 这篇文章出现的刚刚好,太细致了,很好,码起来,关注up主了!希望up主能多写Golang相关的文章。
- 2023-02-09 08:46:25
-
- 细心的冬瓜
- 这篇博文出现的刚刚好,太全面了,很好,mark,关注博主了!希望博主能多写Golang相关的文章。
- 2023-01-20 04:43:15
-
- 沉默的猫咪
- 赞 👍👍,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢博主分享文章内容!
- 2023-01-09 04:31:27
-
- 懦弱的茉莉
- 这篇技术文章真是及时雨啊,很详细,很有用,已收藏,关注博主了!希望博主能多写Golang相关的文章。
- 2023-01-09 01:31:43
-
- 犹豫的耳机
- 赞 👍👍,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢师傅分享文章!
- 2023-01-07 20:40:27
-
- Golang · Go教程 | 6小时前 |
- DebianOpenSSL安装失败的终极解决方案
- 501浏览 收藏
-
- Golang · Go教程 | 7小时前 |
- Debian数据快速提取技巧
- 216浏览 收藏
-
- Golang · Go教程 | 10小时前 |
- Debian系统JS依赖管理终极攻略
- 218浏览 收藏
-
- Golang · Go教程 | 12小时前 |
- Debian上Hadoop作业调度实用技巧
- 100浏览 收藏
-
- Golang · Go教程 | 12小时前 |
- Go语言闭包误区与匿名函数深度解析
- 222浏览 收藏
-
- Golang · Go教程 | 12小时前 |
- Debian系统安全回收数据的正确攻略
- 111浏览 收藏
-
- Golang · Go教程 | 14小时前 |
- Debian高效fetch技巧与使用攻略
- 125浏览 收藏
-
- Golang · Go教程 | 20小时前 |
- Debian邮件服务器升级维护攻略
- 474浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 笔灵AI生成答辩PPT
- 探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
- 15次使用
-
- 知网AIGC检测服务系统
- 知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
- 24次使用
-
- AIGC检测-Aibiye
- AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
- 30次使用
-
- 易笔AI论文
- 易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
- 40次使用
-
- 笔启AI论文写作平台
- 笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
- 35次使用
-
- HTTP 的 response 中的响应体和头部是分开发送的吗?
- 2023-01-28 387浏览
-
- B站等视频网站的弹幕用的是 websocket 还是轮询?
- 2023-02-16 447浏览
-
- Golang实现HTTP编程请求和响应
- 2022-12-28 101浏览
-
- golangNewRequest/gorequest实现http请求的示例代码
- 2023-01-24 343浏览
-
- 一文详解Golang中net/http包的实现原理
- 2022-12-29 419浏览