最近在做一個(gè)需求,功能很簡(jiǎn)單,就是開發(fā)一個(gè)輕量級(jí)客戶端,將一個(gè)指定文件中的內(nèi)容通過 TCP
發(fā)送到服務(wù)器。由于該文件特別大,有可能到達(dá)100G的數(shù)量級(jí),因此處理起來會(huì)比較慢,為了給用戶提供比較友好的展示界面,因此,在其中加入了進(jìn)度條顯示功能。
在這里,說一下我在實(shí)現(xiàn)該進(jìn)度條功能時(shí)的一些思路。
成果演示
先看一下最終的成品效果展示:
該進(jìn)度條一共分三部分組成,第一部分是主體進(jìn)度條,第二部分是百分比,第三部分是當(dāng)前完成的數(shù)據(jù)和總數(shù)據(jù)的一個(gè)動(dòng)態(tài)展示。
源碼分析
由于是要在終端上打印出進(jìn)度條的效果,因此,主要還是利用 fmt.Printf
函數(shù)中的 \r
格式控制符。有了這個(gè)基礎(chǔ),我們就可以先設(shè)計(jì)一下結(jié)構(gòu),如下所示:
type Bar struct { percent int64 //百分比 cur int64 //當(dāng)前進(jìn)度位置 total int64 //總進(jìn)度 rate string //進(jìn)度條 graph string //顯示符號(hào) }
其中,百分比沒什么說的, cur
和 total
是一組,表示的就是第三部分動(dòng)態(tài)展示的當(dāng)前完成數(shù)據(jù)和總數(shù)據(jù)。 rate
就是第一部分不斷變化的進(jìn)度條,它是一個(gè) string
類型的字符串。
這個(gè)進(jìn)度條顯示工具還提供了一個(gè)叫 graph
的屬性,有了它,用戶就可以自定義進(jìn)度條顯示的圖案,比如可以把進(jìn)度條中的方塊換成 #
、 =
、 @
等你可以想得到的圖案。
初始化
為了能夠方便的調(diào)用該進(jìn)度條工具,因此,為該結(jié)構(gòu)提供了兩個(gè)初始化的方法,分別為 NewOption
和 NewOptionWithGraph
,第二個(gè)初始化的方法即可以自己指定顯示圖案。
NewOption
使用的是默認(rèn)的顯示圖案,也就是上圖展示的方框。其實(shí)現(xiàn)代碼如下所示:
func (bar *Bar) NewOption(start, total int64) { bar.cur = start bar.total = total if bar.graph == "" { bar.graph = "█" } bar.percent = bar.getPercent() for i := 0; i int(bar.percent); i += 2 { bar.rate += bar.graph //初始化進(jìn)度條位置 } }
該函數(shù)提供了兩個(gè)參數(shù),分別為 start
和 total
, total
不用說,它代表的是總的任務(wù)量,還提供了一個(gè) start
參數(shù),說明可以不從 0
開始,這也就意味著, 如果你的程序要支持?jǐn)帱c(diǎn)續(xù)傳功能,這個(gè)進(jìn)度條工具依然可以完美支持,只需要將 start
值設(shè)置在斷點(diǎn)處即可。當(dāng)然了,如果你不需要斷點(diǎn)續(xù)傳,每次都從 0
開始,只需要將 start
值設(shè)置為0即可。
如果你注意到我在初始化進(jìn)度條位置的時(shí)候,我使用了 i += 2
的步長(zhǎng),這就是我接下來要說的。因?yàn)榘俜直瓤偸菑?0
到 100
,而我的進(jìn)度條長(zhǎng)度最長(zhǎng)為50個(gè)字符,這也就意味著,每增長(zhǎng) 2%
,進(jìn)度條就要漲一格,因此,這里的步長(zhǎng)為2。
getPercent
是一個(gè)根據(jù) cur
和 total
獲取當(dāng)前進(jìn)度完成百分比的一個(gè)函數(shù),其實(shí)現(xiàn)比較簡(jiǎn)單:
func (bar *Bar) getPercent() int64 { return int64(float32(bar.cur) / float32(bar.total) * 100) }
第二個(gè)初始化函數(shù)就比較容易實(shí)現(xiàn)了,只需要把 graph
重新覆蓋之后,直接調(diào)用上面的初始化函數(shù)即可。
func (bar *Bar) NewOptionWithGraph(start, total int64, graph string) { bar.graph = graph bar.NewOption(start, total) }
進(jìn)度條展示
那么,如何實(shí)現(xiàn)顯示功能呢?
一般調(diào)用顯示進(jìn)度條時(shí),都是放在循環(huán)中執(zhí)行的,因此,我們只需要在循環(huán)中能夠展示出每輪循環(huán)當(dāng)前的進(jìn)度狀態(tài)即可。
func (bar *Bar) Play(cur int64) { bar.cur = cur last := bar.percent bar.percent = bar.getPercent() if bar.percent != last bar.percent%2 == 0 { bar.rate += bar.graph } fmt.Printf("\r[%-50s]%3d%% %8d/%d", bar.rate, bar.percent, bar.cur, bar.total) }
這段代碼中,最重要的就是最后的使用 fmt.Printf
打印的那一句,通過 \r
控制打印效果。
當(dāng)然了,在構(gòu)建 rate
進(jìn)度條時(shí),我需要保存上一次完成的百分比,只有當(dāng)百分比發(fā)生了變化,且步長(zhǎng)變化了 2
時(shí),才需要改變進(jìn)度條的長(zhǎng)度。如果你的屏幕足夠大,你也可以讓你的進(jìn)度條長(zhǎng)度為 100
個(gè)字符,這樣,你就不需要控制進(jìn)度條的步長(zhǎng)為2了,每增長(zhǎng) 1%
,進(jìn)度條前進(jìn)1格,也是沒有問題的。
結(jié)束
由于上面的打印沒有打印換行符,因此,在進(jìn)度全部結(jié)束之后(也就是跳出循環(huán)之外時(shí)),需要打印一個(gè)換行符,因此,封裝了一個(gè) Finish
函數(shù),該函數(shù)純粹的打印一個(gè)換行,表示進(jìn)度條已經(jīng)完成。
func (bar *Bar) Finish(){ fmt.Println() }
如何調(diào)用
調(diào)用該進(jìn)度條功能,首先,肯定要構(gòu)建一個(gè) Bar
對(duì)象,使用該對(duì)象進(jìn)行初始化后,即可完成進(jìn)度條的調(diào)用了,一個(gè)完整的調(diào)用程序如下所示:
func main(){ var bar progressbar.Bar bar.NewOption(0, 100) for i:= 0; i=100; i++{ time.Sleep(100*time.Millisecond) bar.Play(int64(i)) } bar.Finish() }
以上是一個(gè)最簡(jiǎn)單的調(diào)用,其運(yùn)行效果如下所示:
當(dāng)然了,你也可以使用另一個(gè)初始化函數(shù)指定顯示的圖標(biāo),如下所示:
bar.NewOptionWithGraph(0, 100, "#")
展示效果則如下所示:
當(dāng)然,實(shí)際使用中,你太可能只利用睡眠,而是需要實(shí)現(xiàn)自己的函數(shù)功能,只需要將 time.Sleep(100*time.Millisecond)
換成自己的代碼邏輯即可。
到此這篇關(guān)于golang 進(jìn)度條功能實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)golang 進(jìn)度條內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標(biāo)簽:廣西 慶陽 德州 太原 貴陽 阿克蘇 西雙版納 調(diào)研邀請(qǐng)
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《golang 進(jìn)度條功能實(shí)現(xiàn)示例》,本文關(guān)鍵詞 golang,進(jìn)度,條,功能,實(shí)現(xiàn),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。