Skip to content

golang 下载大文件进度

Published: at 07:19 PM | 1 min read

使用io.Copy将下载的部分内容不断写入文件,重载io.Reader的Read函数,使用Read读取数据和大小,通过http的ContentLength获取total大小。

package goutil

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

type ChunkReader struct {
	io.Reader
	Total int64
	Offset int64
	Progress func(offset, total int64)
}

func(r *ChunkReader)Read(b []byte)(n int, err error) {
	n, err = r.Reader.Read(b)
	r.Offset += int64(n)
	if r.Progress != nil {
		r.Progress(r.Offset, r.Total)
	}
	return
}

func DownloadFile(url, filepath string, progress func(offset, total int64)) error {
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	f, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer f.Close()
	r := &ChunkReader{
		Reader: resp.Body,
		Total: resp.ContentLength,
		Progress: progress,
	}
	if _, err := io.Copy(f, r); err != nil {
		return err
	}
	return nil
}

	progress := func(offset, total int64) {
		if total > 0 {
			fmt.Printf("\r%.2f%%", float64(offset*100/total))
		} else {
			fmt.Printf("\r%d", offset)
		}
	}
	url := "http://dldir1.qq.com/weixin/Windows/WeChat_3.2.1_update154.dat"
	goutil.DownloadFile(url, "111.dat", progress)