由于有時候跑腳本幾個小時看不到進度,所以想著寫一個簡單的命令行的進度條。類似下面這樣的
創(chuàng)新互聯(lián)是專業(yè)的確山網(wǎng)站建設(shè)公司,確山接單;提供網(wǎng)站設(shè)計、做網(wǎng)站,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行確山網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
其中的原理主要是\r回車符(將光標(biāo)移動到行首)。這樣的話就可以重新打印一行以覆蓋之前的那一行。
func main() {
for i := 0; i < 10; i++ {
fmt.Printf("\r####")
}
}
// 結(jié)果:只會打印一行
// ####
首先來看進度條的結(jié)構(gòu)。主要就是current:當(dāng)前進度,和一共的任務(wù)數(shù)量total。
type Bar struct {
mu sync.Mutex
graph string // 顯示符號
rate string // 進度條
percent int // 百分比
current int // 當(dāng)前進度位置
total int // 總進度
start time.Time // 開始時間
}
func NewBar(current, total int) *Bar {
bar := new(Bar)
bar.current = current
bar.total = total
bar.start = time.Now()
if bar.graph == "" {
bar.graph = "█"
}
bar.percent = bar.getPercent()
for i := 0; i < bar.percent; i += 2 {
bar.rate += bar.graph //初始化進度條位置
}
return bar
}
func NewBarWithGraph(start, total int, graph string) *Bar {
bar := NewBar(start, total)
bar.graph = graph
return bar
}
根據(jù)當(dāng)前的進度和總的進度來計算任務(wù)進行的百分比。
func (bar *Bar) getPercent() int {
return int((float64(bar.current) / float64(bar.total)) * 100)
}
計算當(dāng)前花費了多少時間 h表示小時,m表示分鐘,s表示多少秒。
func (bar *Bar) getTime() (s string) {
u := time.Now().Sub(bar.start).Seconds()
h := int(u) / 3600
m := int(u) % 3600 / 60
if h > 0 {
s += strconv.Itoa(h) + "h "
}
if h > 0 || m > 0 {
s += strconv.Itoa(m) + "m "
}
s += strconv.Itoa(int(u)%60) + "s"
return
}
使用fmt.Printf 將光標(biāo)設(shè)置到行首并打印進度條,以覆蓋上一個進度條。
func (bar *Bar) load() {
last := bar.percent
bar.percent = bar.getPercent()
if bar.percent != last && bar.percent%2 == 0 {
bar.rate += bar.graph
}
fmt.Printf("\r[%-50s]% 3d%% %2s %d/%d", bar.rate, bar.percent, bar.getTime(), bar.current, bar.total)
}
設(shè)置具體的完成任務(wù)數(shù),或者任務(wù)數(shù)加或者減某個值。
func (bar *Bar) Reset(current int) {
bar.mu.Lock()
defer bar.mu.Unlock()
bar.current = current
bar.load()
}
func (bar *Bar) Add(i int) {
bar.mu.Lock()
defer bar.mu.Unlock()
bar.current += i
bar.load()
}
func main() {
b := bar.NewBar(0,1000)
for i := 0 ;i < 1000; i++ {
b.Add(1)
time.Sleep(time.Millisecond*10)
}
}
至此以上就是全部的代碼,非常簡單,只是指在跑一些簡單任務(wù)的時候能有一個提示。