1. 程式人生 > >Linux中實現一個簡單的進度條【轉】

Linux中實現一個簡單的進度條【轉】

做的 會有 發現 文件 rsquo 實時 時間 改進 常見

轉自:http://blog.csdn.net/yuehailin/article/details/53999288

說起進度條,其實大家常常見到,比如說你在下載視頻或文件的時候,提示你當前下載進度的就是我們今天要說的進度條,進度條的模擬實現是挺簡單的,但是要做的比較實用還是需要註意很多地方的,下來我就一步步的深入分析一下進度條得實現。

1.起初寫下了這樣的代碼,解釋以下幾點:

1>首先我們需要將[ ]固定在左右兩邊,中間預留下空間,然後用“=”進行填充。這裏printf("[%-100s]\r",str); 格式化輸出,‘-’表示左對齊,

100表示固定列寬,然後‘\r’ 表示回車,即每次打印完使光標回到最開始位置 再明確一下,‘\n’和‘\r’這兩個概念:

‘\n’表示換行,換到當前行的下一行,即光標指向下一行最開始的位置;‘\r‘指回車,即光標回到最開始位置。

2>如果不加睡眠時間,結果一下就全打印出來了,但我們想讓它稍微慢一點,畢竟是進度條嘛,而Linux系 統下默認sleep時間單位為秒(s),這樣的話又覺得間隔時間太長了,於是就有了usleep,它是以微妙計的, 其頭文件在#include <unistd.h>下,這些信息不明白了就man一下;

3>如下代碼我們在觀察現象時會發現是隔0.1s在顯示,但是它卻是一段一段顯示的,這就讓人很是郁悶了, 最後才發現是printf的原因,printf是先將要輸出的內容寫到緩沖區裏,然後再刷新。

首先介紹一下UNIX裏面關於標準IO的幾種緩沖機制:

<3.1>全緩沖 ,全緩沖指的是系統在填滿標準IO緩沖區之後才進行實際的IO操作;註意,對於駐留在磁盤上的文件來說通常是由標準IO庫實 施全緩沖。

<3.2>行緩沖,在這種情況下,標準IO在輸入和輸出中遇到換行符時執行IO操作;註意,當流涉及終端的時候,通常使用的是行緩沖。

<3.3>無緩沖,無緩沖指的是標準IO庫不對字符進行緩沖存儲;註意,標準出錯流stderr通常是無緩沖的。

printf是一個行緩沖函數,先寫到緩沖區,滿足條件後,才將緩沖區刷到對應文件中,刷緩沖區的條件如下:
(1)緩沖區填滿;
(2)寫入的字符中有‘\n’ ,‘\r‘;
(3)調用fflush手動刷新緩沖區;
(4)調用scanf要從緩沖區中讀取數據時,也會將緩沖區內的數據刷新;
滿足上面4個條件之一緩沖區就會刷新
下面是代碼實現:

技術分享

看一下效果圖:

技術分享

2.知道了上面按一段一段顯示的原因,下面我們就來改進一下它,通過fflush這個函數就可以解決這個問題。

fflush用於清空緩沖流,這樣就會立刻輸出所有在緩沖區的內容,也就能即時刷新,這樣剛好就滿足了進度條的實時性。

技術分享

下面是效果展示:

技術分享

3.上面基本達到了我們想要的效果,但是還是不好,在你下載文件的時候人家就有一個百分比來提示你下載了多少了,而我們這只有一個進度條,前進了多少還得自己估計,這樣多不好啊,所以我們也來實現一下這種方式。

技術分享

效果圖:

技術分享

4.上面實現的看似都有了該有的效果,但是我們還是會感覺有些欠缺,比如有時候進度條會有停止不前的時候,這個時候我們很難知道程序是在繼續運行還是卡住了,下面我通過一種動態旋轉的圖標對其進行優化。

旋轉圖標自己可以定,“- \ \ | /”或“| / - \ \”都可以

技術分享

效果圖:

技術分享

技術分享

5.最後再提一點,我在運行代碼時就用了兩個命令,make 和./Proc,那是因為我提前就編寫了一個Makefile文件,這樣就方便了我們運行代碼。

下面就來看一下Makefile文件:

技術分享

作為一個好習慣,記得每次在執行完./Proc後make clean一下

技術分享

Linux中實現一個簡單的進度條【轉】