golang 實現一個簡單的命令行進度條


由於有時候跑腳本幾個小時看不到進度,所以想着寫一個簡單的命令行的進度條。類似下面這樣的

其中的原理主要是\r回車符(將光標移動到行首)。這樣的話就可以重新打印一行以覆蓋之前的那一行。

func main() {
	for i := 0; i < 10; i++ {
		fmt.Printf("\r####")
	}
}
// 結果:只會打印一行
// ####

首先來看進度條的結構。主要就是current:當前進度,和一共的任務數量total。

type Bar struct {
	mu      sync.Mutex
	graph   string    // 顯示符號
	rate    string    // 進度條
	percent int       // 百分比
	current int       // 當前進度位置
	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
}

計算當前百分比

根據當前的進度和總的進度來計算任務進行的百分比。

func (bar *Bar) getPercent() int {
	return int((float64(bar.current) / float64(bar.total)) * 100)
}

獲取當前花費時間

計算當前花費了多少時間 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 將光標設置到行首並打印進度條,以覆蓋上一個進度條。

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)
}

設置進度

設置具體的完成任務數,或者任務數加或者減某個值。

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)
	}

} 

至此以上就是全部的代碼,非常簡單,只是指在跑一些簡單任務的時候能有一個提示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM