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 检查网络状态是否正常的方法
- 下一篇
- 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小时前 | go · Go 交叉编译 GOARCH GOOS CGO_ENABLED
- Go 交叉编译怎样关闭 CGO
- 487浏览 收藏
-
- Golang · Go教程 | 6小时前 | go · Go教程 · go.work Go Modules go work 多模块联调
- Go work 怎样管理多个模块联调
- 245浏览 收藏
-
- Golang · Go教程 | 6小时前 | Go教程 · Go 模块依赖 Go Modules go mod why 依赖路径
- Go mod why 怎样解释模块引入路径
- 394浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Go net/url 怎样只修改查询参数而保留路径
- 274浏览 收藏
-
- Golang · Go教程 | 6小时前 | goroutine · go ·
- Go trace 怎样观察 goroutine 调度
- 351浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Go pprof 怎样定位 CPU 热点函数
- 321浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Go benchmark 怎样排除初始化耗时
- 266浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 586次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 622次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 656次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 622次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 438次使用
-
- Golang实现HTTP编程请求和响应
- 2022-12-28 101浏览
-
- golangNewRequest/gorequest实现http请求的示例代码
- 2023-01-24 343浏览
-
- 一文详解Golang中net/http包的实现原理
- 2022-12-29 419浏览
-
- 快速掌握Go语言HTTP标准库的实现方法
- 2022-12-30 327浏览
-
- Go http请求排队处理实战示例
- 2022-12-23 265浏览

