参考:
https://github.com/vbauerster/mpb
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"sync"
"github.com/vbauerster/mpb/v7"
"github.com/vbauerster/mpb/v7/decor"
)
type Resource struct {
Filename string
Url string
}
type DownLoad struct {
Resources []Resource
Dir string
wg *sync.WaitGroup
}
func main() {
d := NewDownload("./")
d.AppendResource("1.zip", "http://192.168.1.50:5000/api/v3/file/get/96/Etcher_V1.5.70_XiTongZhiJia.zip?sign=f9hI4r4KXjCwew9J5l2Xvcia8CAd4FQc_qxBA_Kczg4%3D%3A0")
d.AppendResource("2.exe", "http://192.168.1.50:5000/api/v3/file/get/97/JDSoft_SurfMill8.0_X64_Pro_Setup.exe?sign=V7d4TW1HzZhWcBQj_MtNyVD4BonhsMpVTN6yzJ7iZyY%3D%3A0")
d.Start()
}
func NewDownload(dir string) *DownLoad {
return &DownLoad{
Dir: dir,
wg: &sync.WaitGroup{},
}
}
func (d *DownLoad) AppendResource(filename, url string) {
d.Resources = append(d.Resources, Resource{
Filename: filename,
Url: url,
})
}
func (d *DownLoad) Start() {
p := mpb.New(mpb.WithWaitGroup(d.wg))
for _, v := range d.Resources {
d.wg.Add(1)
go d.download(v, p)
}
p.Wait()
d.wg.Wait()
}
func (d *DownLoad) download(r Resource, p *mpb.Progress) {
defer d.wg.Done()
req, err := http.NewRequest("GET", r.Url, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Get失败", err)
}
defer resp.Body.Close()
fileSize, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
var total int64 = int64(fileSize)
bar := p.Add(int64(fileSize),
mpb.NewBarFiller(mpb.BarStyle().Rbound("|")),
mpb.PrependDecorators(
decor.Name(r.Filename, decor.WC{W: len(r.Filename) + 1, C: decor.DidentRight}),
decor.CountersKibiByte("% .2f / % .2f"),
),
mpb.AppendDecorators(
decor.EwmaETA(decor.ET_STYLE_GO, 90),
decor.Name(" ] "),
decor.EwmaSpeed(decor.UnitKiB, "% .2f", 60),
),
)
file, err := os.Create(r.Filename)
if err != nil {
fmt.Println("创建文件失败", err)
}
defer file.Close()
// create proxy reader
reader := io.LimitReader(resp.Body, total)
proxyReader := bar.ProxyReader(reader)
defer proxyReader.Close()
// copy from proxyReader, ignoring errors
_, err = io.Copy(file, proxyReader)
if err != nil {
fmt.Println("写入文件失败", err)
}
}