Golang 实现带进度条的文件下载功能

发表时间: 2024-05-21 11:16

普通文件下载

package mainimport ("io""net/http""os")func main() {    // 下载地址:    fileUrl := "http://xxxxxx.com/files/"    if err := DownloadFile("保存文件名.png", fileUrl); err != nil {    panic(err)    }    }    // download file会将url下载到本地文件,它会在下载时写入,而不是将整个文件加载到内存中。    func DownloadFile(filepath string, url string) error {    // Get the data    resp, err := http.Get(url)    if err != nil {    return err    }    defer resp.Body.Close()    // Create the file    out, err := os.Create(filepath)    if err != nil {    return err    }    defer out.Close()    // Write the body to file    _, err = io.Copy(out, resp.Body)    return err}

带进度条的大文件下载

package mainimport (    "fmt"    "io"    "net/http"    "os"    "strings"    "github.com/dustin/go-humanize")type WriteCounter struct {    Total uint64}func (wc *WriteCounter) Write(p []byte) (int, error) {    n := len(p)    wc.Total += uint64(n)    wc.PrintProgress()    return n, nil}func (wc WriteCounter) PrintProgress() {    fmt.Printf("\r%s", strings.Repeat(" ", 35))    fmt.Printf("\rDownloading... %s complete", humanize.Bytes(wc.Total))}func main() {    fmt.Println("Download Started")    // 下载地址:    fileUrl := "http://xxxxxx.com/files/文件名称""    err := DownloadFile("保存文件名.png", fileUrl)    if err != nil {        panic(err)    }    fmt.Println("Download Finished")}func DownloadFile(filepath string, url string) error {    out, err := os.Create(filepath + ".tmp")    if err != nil {        return err    }    resp, err := http.Get(url)    if err != nil {        out.Close()        return err    }    defer resp.Body.Close()    counter := &WriteCounter{}    /*    io.TeeReader则可以传递计数器来跟踪进度    io.TeeReader返回一个将其从r读取的数据写入w的Reader接口。所有通过该接口对r的读取都会执行对应的对w的写入。没有内部的缓冲;    写入必须在读取完成前完成。写入时遇到的任何错误都会作为读取错误返回。    */    if _, err = io.Copy(out, io.TeeReader(resp.Body, counter)); err != nil {        out.Close()        return err    }    fmt.Print("\n")    out.Close()    if err = os.Rename(filepath+".tmp", filepath); err != nil {        return err    }    return nil}