通過小程序進度條了解Linux下的多文件操作

在網絡中,進度條隨處可見,無論是下載還是上傳,進度條都幫助我們判斷當前的進展情況。然而,今天我們將討論的進度條僅具備外觀。首先,讓我們了解一下回車的概念。

1.1 回車的概念

在計算機出現之前,有一種名為電傳打字機(Teletype Model 33)的機械打字機,每秒鐘可以打10個字符。但在換行時需要0.2秒,這段時間內如果有新字符傳輸過來,字符可能會丟失。為了解決這個問題,研發人員在每行結尾添加了兩個結束字符:一個是“回車”,指示打字機將打印頭定位到左邊界而不卷動滾筒;另一個是“換行”,指示打字機卷動滾筒而不改變水平位置。隨著計算機的發明,這兩個概念被引入計算機中。由于存儲器昂貴,一些科學家認為在每行結尾添加兩個字符太浪費,因此出現了分歧。

回車 的本義是將光標重新回到本行的開頭,英文為return,控制字符為CR(Carriage Return)。換行 的本義是將光標移到下一行(不一定是下一行的行首),英文為newline,控制字符為LF(Line Feed)。

符號 ASCII 意義
10 換行NL
13 回車CR

在進度條中,我們需要使用 來將光標回到一行的開頭。

1.2 緩沖區的概念

緩沖區是內存的一部分,用于暫存輸入或輸出的數據。根據對應的是輸入設備還是輸出設備,緩沖區分為輸入緩沖區和輸出緩沖區。當我們使用printf函數時,內容先進入緩沖區,然后再從緩沖區打印到屏幕。由于代碼中存在sleep,緩沖區的內容不會立即打印到屏幕,這會影響進度條的運行。因此,需要使用fflush強制將緩沖區的內容輸出。輸出緩沖區的流是stdout,將stdout作為fflush函數的參數即可輸出內容。大家可以嘗試以下代碼:

通過小程序進度條了解Linux下的多文件操作

#include <stdio.h> #include <unistd.h> int main(){     printf("hello makefile");     sleep(3);     return 0; }

1.3 makefile的準備

為了充分利用linux下的makefile,本次進度條將分為以下三個文件編寫:

progressbar.c  progressbar.h  test.c

在編寫之前,我們先配置makefile的內容:

progressbar:test.o progressbar.o     gcc -o progressbar test.o progressbar.o test.o:test.c     gcc -c test.c progressbar.o:progressbar.c     gcc -c progressbar.c .PHONY:clean clean:     rm -f progressbar progressbar.o test.o

配置完成后,在progressbar.h中編寫本次程序可能用到的頭文件:

#pragma once #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <string.h> typedef void(*callback_c)(double rate); //函數指針 void progress();//進度條1.0 void progress2(double rate);//進度條2.0

1.4 進度條1.0

旋轉光標的存在是為了模擬現實中進度條卡住的情況,判斷進度條是否還在運行。

char load[4] = {'|','/','-',''};//旋轉光標 void progress(){     char str[101];     memset(str,0,sizeof(str));     int i = 0;     for(i = 0;i<100;i++){         str[i] = '#';         printf("[%-100s][%d%%][%c] ",str,i+1,load[i%4]);         fflush(stdout);         usleep(50000);     }     printf(" "); }

這個進度條僅具備外觀,沒有實際意義。

1.5 進度條2.0

模擬下載過程,通過當前下載的比例來判斷進度。

char p_str[101]; void progress2(double rate){     int cnt = (int)rate;     printf("[%-100s][%.1lf%%][%c] ",p_str,rate,load[cnt%4]);     fflush(stdout);     p_str[(int)rate] = '#'; } #include "progressbar.h" int filesize = 1024*1024*1024;//假設文件大小為1GB void download(callback_c cb){     //模擬下載過程     srand((unsigned int)time(NULL));//隨機下載文件的大小     int total = filesize;//已下載文件的大小     while(total>0)     {         usleep(20000);         int load = rand()%(1024*1024*10);//下載速度0~1MB*10         total-=load;         if(total<0) total = 0;         double rate = (double)(filesize-total)/filesize*100;         cb(rate);     }     printf(" "); }

? 版權聲明
THE END
喜歡就支持一下吧
點贊9 分享