go 下载文件显示进度条

1,130 阅读1分钟
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

// 自定义个下载器,实现io.Reader接口
type MyDownloader struct {
	io.Reader       // 读取器
	Total     int64 // 总大小
	Current   int64 // 当前大小
}

// 实现io.Reader接口的Read方法
// p是一个字节切片,n是读取的字节数,err是错误信息
func (d *MyDownloader) Read(p []byte) (n int, err error) {
	n, err = d.Reader.Read(p)
	d.Current += int64(n)
	// 这里可以打印下载进度
	fmt.Printf("\r正在下载,下载进度:%.2f%%", float64(d.Current*10000/d.Total)/100)
	if d.Current == d.Total {
		fmt.Printf("\r下载完成,下载进度:%.2f%%", float64(d.Current*10000/d.Total)/100)
	}
	return
}

func downloadFile(url, filePath string) {
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	file, err := os.Create(filePath)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	myDownloader := &MyDownloader{
		Reader: resp.Body,
		Total:  resp.ContentLength,
	}
	if _, err := io.Copy(file, myDownloader); err != nil {
		panic(err)
	}
}

func main() {
	url := "https://zme-caps.amazon.com/t/EKUMJMIvkrHK/lrKTtMebcbn0ZIWZqsr2GGNPBc-BxtGxR28ME-X6bPk/17"
	filename := "./wegame.zip"
	downloadFile(url, filename)
}