进度条

作者: 司空儿 | 来源:发表于2019-11-13 13:54 被阅读0次

整个实现中,最重要的是 WriteCounter 这个结构体,这个结构体下的 Write(p []byte) 方法的参数 p 就是每段读取的内容。


package main

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

// WriteCounter counts the number of bytes written to it. It implements to the io.Writer
// interface and we can pass this into io.TeeReader() which will report progress on each
// write cycle.
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() {
    // Clear the line by using a character return to go back to the start and remove
    // the remaining characters by filling it with spaces
    fmt.Printf("\r%s", strings.Repeat(" ", 35))

    // Return again and print current status of download
    // We use the humanize package to print the bytes in a meaningful way (e.g. 10 MB)
    fmt.Printf("\rDownloading... %d B complete", wc.Total)
}

func main() {
    fmt.Println("Download Started")

    fileUrl := "https://dl.google.com/go/go1.11.1.src.tar.gz"
    err := DownloadFile("go1.11.1.src.tar.gz", fileUrl)
    if err != nil {
        panic(err)
    }

    fmt.Println("Download Finished")
}

// DownloadFile will download a url to a local file. It's efficient because it will
// write as it downloads and not load the whole file into memory. We pass an io.TeeReader
// into Copy() to report progress on the download.
func DownloadFile(filepath string, url string) error {

    // Create the file, but give it a tmp file extension, this means we won't overwrite a
    // file until it's downloaded, but we'll remove the tmp extension once downloaded.
    out, err := os.Create(filepath + ".tmp")
    if err != nil {
        return err
    }
    defer out.Close()

    // Get the data
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    // Create our progress reporter and pass it to be used alongside our writer
    counter := &WriteCounter{}
    _, err = io.Copy(out, io.TeeReader(resp.Body, counter))
    if err != nil {
        return err
    }

    // The progress use the same line so print a new line once it's finished downloading
    fmt.Print("\n")

    err = os.Rename(filepath+".tmp", filepath)
    if err != nil {
        return err
    }

    return nil
}

转自https://www.twle.cn/t/385

相关文章

  • sys模块

    打印进度条 进度条的效果 [# ][## ][### ...

  • 橡皮筋进度条ElasticProgressBar

    橡皮筋进度条ElasticProgressBar 橡皮筋进度条是一个极具动画效果的进度条。该进度条不仅具有皮筋效果...

  • Android SeekBar的使用,进度条的另一种实现方式

    概述: SeekBar是进度条。我们使用进度条时,可以使用系统默认的进度条;也可以自定义进度条的图片和滑块图片等。...

  • Android控件之SeekBar

    SeekBar是进度条。我们使用进度条时,可以使用系统默认的进度条;也可以自定义进度条的图片和滑块图片等。 See...

  • Android进度条

    Android进度条 不同的进度条显示结果: demo xml代码: 二.模拟进度条加载过程:运行展示图: xml...

  • SeekBar的用法

    1)ProgressBar (一般进度条,例如:下载进度条)2)SeekBar(拖动条,适用于音乐,视频播放进度条...

  • 设置进度条的样式

    1.首先是水平进度条 2.分别设置进度条的第一、第二进度条的样式和进度条背景的样式。新建一个文件progressb...

  • IOS开发 UISlider和UIProgressView

    进度条和滑动动条控件 本节学习内容: 1.进度条和滑动条的概念 2.进度条和滑动条的属性 3.进度条和滑动条的使用...

  • ProgressBar进度条

    SeekBar :搜寻进度条RatingBar:评价进度条 style="?android:attr/progre...

  • Android中常用UI控件ProgressBar

    ProgressBar表示进度条, 应用场景也很多,比如下载时候的进度条, 程序更新时候的进度条. 我们今天用昨天...

网友评论

      本文标题:进度条

      本文链接:https://www.haomeiwen.com/subject/vtvhictx.html