Linux C實現檔案拷貝可變色進度條顯示
阿新 • • 發佈:2018-12-12
printf的格式化輸出中,可以設定前景色和背景色,因此進度條的顏色可以通過printf的格式化輸出來實現;此外,進度條的實現主要依靠"\r"和"fflush(stdout)“來支援。”\r" 用來回到行首而不換行,fflush(stdout)是重新整理螢幕輸出緩衝區。只要根據進度,重新填寫緩衝區內容,然後fflush()重新整理緩衝區,重新在螢幕上列印緩衝區內容則可以動態實現進度條。
測試程式碼(在Redhat6.4中gcc編譯):
/* * Time:2018年9月30日13:24:35 * Author:Kangruojin * Version:V2.0 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #define MAX_STR_LEN 101 #define SIZE_BIT_KB 10 /* 單位為KB */ #define _PROGRESS_BAR_RED "\033[31m[%-100s][%d%%][%c][%dKB - %dKB]\r\033[0m" #define _PROGRESS_BAR_BLUE "\033[34m[%-100s][%d%%][%c][%dKB - %dKB]\r\033[0m" #define _PROGRESS_BAR_GREEN "\033[32m[%-100s][%d%%][%c][%dKB - %dKB]\r\033[0m" #define PRINT_RED(format,...) printf(_PROGRESS_BAR_RED, ##__VA_ARGS__) #define PRINT_GREEN(format,...) printf(_PROGRESS_BAR_BLUE, ##__VA_ARGS__) #define PRINT_YELLOW(format,...) printf(_PROGRESS_BAR_GREEN, ##__VA_ARGS__) void progressBar(int pre, int cur, int cs, int fs); int main(int argc, char **argv) { if(argc != 4) { printf("parameter error:./progressBar srcFileName dstFileName buffSize\n"); printf("buffSize choose min value is 8192,It's fast!\n"); exit(EXIT_FAILURE); } int ret_r = 0, ret_w = 0, curSize = 0, fileSize = 0, cur = 0, pre = 0, shr = SIZE_BIT_KB; int bufSize = atoi(argv[3]); char * pBuff = (char *)malloc(bufSize); if(NULL == pBuff){ perror("malloc"); } memset(pBuff, 0, bufSize); int fdr = open(argv[1], O_RDONLY); int fdw = open(argv[2], O_RDWR | O_CREAT | O_TRUNC); if(fdw < 0 || fdr < 0){ perror("open File"); } fileSize = lseek(fdr, 0, SEEK_END); lseek(fdr, 0, SEEK_SET); while((ret_r = read(fdr, pBuff, bufSize)) > 0){ if((ret_w = write(fdw, pBuff, ret_r)) != ret_r){ perror("write");/* 寫的位元組數與實際寫入的數目不同 */ } /* 根據已複製檔案大小和總檔案大小計算進度(x%) */ curSize += ret_w; pre = cur; cur = (int)(((double)curSize / fileSize) * 100); if(cur > pre) { progressBar(pre, cur, curSize >> shr, fileSize >> shr); } memset(pBuff, 0, ret_r); } printf("\n"); free(pBuff); close(fdr); close(fdw); return 0; } /****************************************************************************** * Time:2018年9月30日13:23:31 * printf()的顏色格式:\033[{attr1};{attr2};...{attrn}m * 以\033即Esc的ASCII開始,跟隨n個屬性,以m結尾 * eg:\033[32;41m * attr屬性取值: * 0:重置所有屬性;1:高亮/加粗;2:暗淡;4:下滑線;5:閃爍;6:反轉;8:隱藏 * 30~37為前景色,40~47為背景色,依次是: * 黑 紅 綠 黃 藍 紫 青 白 * 30 31 32 33 34 35 36 37 * 40 41 42 43 44 45 46 47 * ****************************************************************************/ void progressBar(int pre, int cur, int cs, int fs) { if(pre < 0 || pre > 100 || cur < 0 || cur > 100) { perror("error progress!!\n"); } static char str[MAX_STR_LEN] = {0}; static char table[] = "-\\|/"; int i = 0; for(i = pre; i < cur; i++){ str[i] = '#'; } if(cur < 33){ PRINT_RED(str, cur, table[cur%4], cs, fs); } else if(cur < 66){ PRINT_BLUE(str, cur, table[cur%4], cs, fs); } else{ PRINT_GREEN(str, cur, table[cur%4], cs, fs); } fflush(stdout); }