模拟实现Linux中的进度条
引言
模拟实现Linux中的进度条
一、前置知识
回车换行是两个动作:\n = \r + \n
运行这段代码会发现,打印会在sleep3秒后进行,为什么是这样的呢?
1 #include<stdio.h> 2 #include<unistd.h>3 4 5 int main()6 {7 printf("hello word");8 sleep(3);9 return 0;10 }
因为打印函数的内容在缓冲区里面(在内存里面),需要刷新一下屏幕的缓冲区才可以显示出来。
当加上\n时,就可以先打印后sleep3秒。说明屏幕缓冲区的内容是按行刷新的。
所以可以用fflush函数来手动刷新缓冲区:
1 #include<stdio.h>2 #include<unistd.h>3 4 5 int main()6 {7 printf("hello word");8 fflush(stdout);9 sleep(3); 10 return 0;11 }
二、先实现一个倒计时程序
1 #include<stdio.h>2 #include<unistd.h>3 4 5 6 7 int main()8 {9 int i = 10;10 for(; i >= 0; i--)11 {12 printf("clock:%2d\r",i); 13 fflush(stdout);14 sleep(1);15 }16 printf("\n");17 18 return 0;19 }
主要是掌握一下对上面知识的运用。
三、模拟实现进度条
版本1:
process.c文件中:
1 #include"process.h"2 #include<unistd.h>3 #include<string.h>4 5 #define SIZE 1016 #define STYLE '='7 8 9 void Process()10 {11 const char* lable = "|/-\\";12 int len = strlen(lable);13 char processbuff[SIZE];14 memset(processbuff, '\0', sizeof(processbuff));15 16 int cnt = 0;17 while(cnt <= 100)18 {19 printf("[%-100s] [%d%%][%c]\r", processbuff, cnt, lable[cnt%len]); 20 fflush(stdout);21 processbuff[cnt++] = STYLE;22 usleep(30000);23 }24 printf("\n");25 26 27 }
很显然,版本1只是简单模拟了一下进度条,非常不实际,所以实现一个版本2
版本2:
process.h文件中:
1 #pragma once 2 #include<stdio.h>3 4 void Process();5 void FlushProcess(double total, double curr); //更新进度,按照下载进度,更新进度条 6
process.c文件中:
1 #include"process.h"2 #include<unistd.h>3 #include<string.h>4 5 #define SIZE 1016 #define STYLE '='7 8 9 void FlushProcess(double total, double curr) //更新进度,按照下载进度,更新进度条 10 {11 if(curr > total)12 curr = total;13 double rate = curr / total * 100;14 int cnt = (int)rate;15 char processbuff[SIZE];16 memset(processbuff, '\0', sizeof(processbuff));17 int i = 0;18 for(;i < cnt; i++)19 {20 processbuff[i] = STYLE;21 }22 23 static const char *lable = "|/-\\";24 static int index = 0;25 26 printf("[%-100s][%.1lf%%][%c]\r", processbuff, rate, lable[index++]);27 index %= strlen(lable);28 fflush(stdout);29 if(curr >= total) 30 {31 printf("\n");32 }33 34 35 36 }
main.c文件中:
1 #include<stdio.h>2 #include"process.h"3 #include<time.h>4 #include<stdlib.h>5 #include<unistd.h>6 7 double gtotal = 1024.0;8 double speed = 1.0;9 10 typedef void (*callback_t)(double, double);11 12 double SpeedFloat(double start, double range) //模拟不同的速度13 {14 int int_range = (int)range;15 return start + rand()%int_range + (range - int_range);16 }17 18 void Download(int total, callback_t cb ) //模拟下载 19 {20 srand(time(NULL));21 double curr = 0;22 while(1)23 {24 if(curr > total) 25 {26 curr = total; //模拟下载完成27 cb(total, curr); //更新进度,按照下载进度,进行更新进度条28 break;29 }30 cb(total, curr);31 curr += SpeedFloat(speed, 20.3); //模拟下载行为32 usleep(30000);33 }34 }35 36 37 38 int main()39 {40 printf("download: 20.0MB\n");41 Download(20.0, FlushProcess);42 printf("download: 2000.0MB\n");43 Download(2000.0, FlushProcess);44 printf("download: 100.0MB\n");45 Download(100.0, FlushProcess);46 printf("download: 20000.0MB\n");47 Download(20000.0, FlushProcess);48 49 return 0;50 }
运行结果: