dongshuo9350 2015-05-29 15:00
浏览 193
已采纳

golang动态进度条

I'm trying file download with golang.

I'm downloading file it's okay. After I'm using cheggaaa's progressbar library. But I can't dynamic.

How can I do dynamic progressbar?

My code below:

package main

import (
    "flag"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
    "strings"
    "github.com/cheggaaa/pb"
    "time"
)

/*
    usage = usage text
    version = current number
    help use Sprintf
    *cliUrl from cmd
    *cliVersion from cmd
    *cliHelp * from cmd
*/
var (
    usage      = "Usage: ./gofret -url=http://some/do.zip"
    version    = "Version: 0.1"
    help       = fmt.Sprintf("

  %s


  %s", usage, version)
    cliUrl     *string
    cliVersion *bool
    cliHelp    *bool
)

func init() {
    /*
        if *cliUrl != "" {
            fmt.Println(*cliUrl)
        }

        ./gofret -url=http://somesite.com/somefile.zip
        ./gofret -url=https://github.com/aligoren/syspy/archive/master.zip
    */
    cliUrl = flag.String("url", "", usage)

    /*
        else if *cliVersion{
            fmt.Println(flag.Lookup("version").Usage)
        }

        ./gofret -version
    */
    cliVersion = flag.Bool("version", false, version)

    /*
        if *cliHelp {
            fmt.Println(flag.Lookup("help").Usage)
        }

        ./gofret -help
    */
    cliHelp = flag.Bool("help", false, help)
}

func main() {

    /*
        Parse all flags
    */
    flag.Parse()

    if *cliUrl != "" {
        fmt.Println("Downloading file")

        /* parse url from *cliUrl */
        fileUrl, err := url.Parse(*cliUrl)

        if err != nil {
            panic(err)
        }

        /* get path from *cliUrl */
        filePath := fileUrl.Path

        /*
            seperate file.
            http://+site.com/+(file.zip)
        */
        segments := strings.Split(filePath, "/")

        /*
            file.zip filename lenth -1
        */
        fileName := segments[len(segments)-1]

        /*
            Create new file.
            Filename from fileName variable
        */
        file, err := os.Create(fileName)

        if err != nil {
            fmt.Println(err)
            panic(err)
        }
        defer file.Close()

        /*
            check status and CheckRedirect
        */
        checkStatus := http.Client{
            CheckRedirect: func(r *http.Request, via []*http.Request) error {
                r.URL.Opaque = r.URL.Path
                return nil
            },
        }

        /*
            Get Response: 200 OK?
        */
        response, err := checkStatus.Get(*cliUrl)

        if err != nil {
            fmt.Println(err)
            panic(err)
        }
        defer response.Body.Close()
        fmt.Println(response.Status) // Example: 200 OK

        /*
            fileSize example: 12572 bytes
        */
        fileSize, err := io.Copy(file, response.Body)
        /*
            progressbar worked after download :(
        */
        var countSize int = int(fileSize/1000)
        count := countSize
        bar := pb.StartNew(count)
        for i := 0; i < count; i++ {
            bar.Increment()
            time.Sleep(time.Millisecond)
        }
        bar.FinishPrint("The End!")

        if err != nil {
            panic(err)
        }


        fmt.Printf("%s with %v bytes downloaded", fileName, count)

    } else if *cliVersion {
        /*
            lookup version flag's usage text
        */
        fmt.Println(flag.Lookup("version").Usage)
    } else if *cliHelp {
        /*
            lookup help flag's usage text
        */
        fmt.Println(flag.Lookup("help").Usage)
    } else {
        /*
            using help's usage text for handling other status
        */
        fmt.Println(flag.Lookup("help").Usage)
    }
}

While the my program is running:

Downloading file
200 OK

After download working progressbar:

6612 / 6612 [=====================================================] 100.00 % 7s
The End!
master.zip with 6612 bytes downloaded

My progressbar code below:

/*
    progressbar worked after download :(
*/
var countSize int = int(fileSize/1000)
count := countSize
bar := pb.StartNew(count)
for i := 0; i < count; i++ {
    bar.Increment()
    time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")

How can I solve progressbar problem?

  • 写回答

2条回答 默认 最新

  • doubao7287 2015-06-16 11:25
    关注

    More goroutines is not needed. Just read from bar

    // start new bar
    bar := pb.New(fileSize).SetUnits(pb.U_BYTES)
    bar.Start()
    // create proxy reader
    rd := bar.NewProxyReader(response.Body)
    // and copy from reader
    io.Copy(file, rd)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 R语言卸载之后无法重装,显示电脑存在下载某些较大二进制文件行为,怎么办
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?
  • ¥15 关于#vue.js#的问题:修改用户信息功能图片无法回显,数据库中只存了一张图片(相关搜索:字符串)
  • ¥15 texstudio的问题,