91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
|
package utils
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// 进度条定义
|
||
|
type ProgressBar struct {
|
||
|
Name string // 名称
|
||
|
Total Counter // 总任务数
|
||
|
Current *Counter // 当前已完成数量
|
||
|
startTime time.Time // 任务开始时间
|
||
|
exit chan struct{} // 是否退出进度条
|
||
|
alreadyOutput bool
|
||
|
}
|
||
|
|
||
|
// 完成指定数量的任务
|
||
|
func (pgb *ProgressBar) Done(i ...int64) {
|
||
|
if len(i) == 1 {
|
||
|
pgb.Current.Add(i[0])
|
||
|
} else {
|
||
|
pgb.Current.Add(1)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 退出进度条
|
||
|
func (pgb *ProgressBar) Exit() {
|
||
|
pgb.exit <- struct{}{}
|
||
|
if pgb.alreadyOutput {
|
||
|
fmt.Println("")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 启动并显示进度条
|
||
|
func (pgb *ProgressBar) Run() {
|
||
|
for {
|
||
|
select {
|
||
|
case <-pgb.exit:
|
||
|
return
|
||
|
case <-time.After(time.Second):
|
||
|
pgb.print()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 输出进度
|
||
|
func (pgb *ProgressBar) print() {
|
||
|
var percent float64 = 0
|
||
|
var per, surplus int64
|
||
|
|
||
|
cur := pgb.Current.Get()
|
||
|
if pgb.Total.Get() > 0 {
|
||
|
percent = float64(cur) / float64(pgb.Total.Get())
|
||
|
}
|
||
|
useTime := int64(time.Now().Sub(pgb.startTime) / time.Second)
|
||
|
if useTime > 0 {
|
||
|
per = cur / useTime
|
||
|
}
|
||
|
if per > 0 {
|
||
|
surplus = (pgb.Total.Get() - cur) / per
|
||
|
}
|
||
|
|
||
|
fmt.Printf("\r\x1b[36m%s[%.2f%%] %d/%d %d/ps used:%s surplus:%s\x1b[0m", pgb.Name, percent * 100, cur, pgb.Total.Get(), per, HumanTimeSecond(useTime), HumanTimeSecond(surplus))
|
||
|
|
||
|
if !pgb.alreadyOutput {
|
||
|
pgb.alreadyOutput = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 创建一个进度条
|
||
|
func NewPGBar(total int64, name ...string) *ProgressBar {
|
||
|
var n string
|
||
|
if len(name) == 1 && name[0] != "" {
|
||
|
n = name[0] + " "
|
||
|
}
|
||
|
return &ProgressBar{
|
||
|
Name: n,
|
||
|
Total: Counter{v : total},
|
||
|
Current: &Counter{},
|
||
|
startTime: time.Now(),
|
||
|
exit: make(chan struct{}, 1),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 生成一个新的进度条并运行
|
||
|
func NewAndRunPGBar(total int64, name ...string) *ProgressBar {
|
||
|
pgb := NewPGBar(total, name...)
|
||
|
go pgb.Run()
|
||
|
return pgb
|
||
|
}
|