服务器 > 服务器 > Linux

Linux在命令行环境中实现进度条的原理解析

19人参与 2025-10-16 Linux

引言

在linux命令行环境中,进度条是一种直观展示任务执行进度的重要方式。

本文将通过一个简单的c语言进度条程序,深入解析其实现原理和优化过程

进度条基础原理

进度条的核心功能是将一个耗时操作的完成情况以可视化的方式展示给用户。在命令行环境中,我们通常使用字符界面来实现这一功能。

一个基本的进度条需要包含以下元素:

基础版进度条实现

我们先来看第一个版本的进度条实现:

// process.h
#pragma once
#include <stdio.h>
//v1
void process();
// process.c (v1部分)
#include "process.h"
#include <string.h>
#include <unistd.h>

#define size 101
#define style '='

// v1: 展示进度条基本功能
void process()
{
    int rate = 0;
    char buffer[size];
    memset(buffer, 0, sizeof(buffer));
    const char *lable = "|/-\\";
    int len = strlen(lable);

    while(rate <= 100)
    {
        printf("[%-100s][%d%%][%c]\r", buffer, rate, lable[rate%len]);
        fflush(stdout);
        buffer[rate] = style;
        rate++;
        usleep(10000);
    }

    printf("\n");
}

这个基础版本的进度条实现了以下功能:

关键点解析:

\r的作用:将光标移动到行首,实现覆盖刷新

输出缓冲区刷新:确保每次输出立即显示

旋转动画:通过数组循环选择不同字符实现

解耦与通用化设计

基础版本虽然实现了进度条的基本功能,但存在明显的局限性:

为了解决这些问题,我们来看第二个版本的实现:

// process.h (v2部分)
//v2
void flushprocess(const char*, double total, double current);
// process.c (v2部分)
#include "process.h"
#include <string.h>
#include <unistd.h>

#define size 101
#define style '='

//v2: 根据进度,动态刷新一次进度条
void flushprocess(const char *tips, double total, double current)
{
    const char *lable = "|/-\\";
    int len = strlen(lable);
    static int index = 0;
    char buffer[size];
    memset(buffer, 0, sizeof(buffer));

    double rate = current*100.0/total;
    int num = (int)rate;

    int i = 0;
    for(; i < num; i++)
        buffer[i] = style;

    printf("%s...[%-100s][%.1lf%%][%c]\r", tips, buffer, rate, lable[index++]);
    fflush(stdout);
    index %= len;

    if(num >= 100)printf("\n");
}

这个版本的主要改进在于:

解耦后的进度条函数具有更好的通用性,可以应用于各种不同的场景。

回调机制与业务集成

为了将进度条应用到实际业务中,我们采用回调函数机制:

// main.c
#include "process.h"
#include <unistd.h>
#include <time.h>
#include <stdlib.h>

//函数指针类型
typedef void (*call_t)(const char*,double,double);

double total = 1024.0;
double speed[] = {1.0, 0.5, 0.3, 0.02, 0.1, 0.01};

//回调函数
void download(int total, call_t cb)
{
    srand(time(null));
    double current = 0.0;
    while(current <= total)
    {
        cb("下载中", total, current); // 进行回调
        if(current>=total) break;
        // 下载代码
        int random = rand()%6;
        usleep(5000);
        current += speed[random];
        if(current>=total) current = total;
    }
}

void uploadload(int total, call_t cb)
{
    srand(time(null));
    double current = 0.0;
    while(current <= total)
    {
        cb("上传中", total, current); // 进行回调
        if(current>=total) break;
        // 下载代码
        int random = rand()%6;
        usleep(5000);
        current += speed[random];
        if(current>=total) current = total;
    }
}

int main()
{
    download(1024.0, flushprocess);
    printf("download 1024.0mb done\n");
    download(512.0, flushprocess);
    printf("download 512.0mb done\n");
    download(256.0,flushprocess);
    printf("download 256.0mb done\n");
    download(128.0,flushprocess);
    printf("download 128.0mb done\n");
    download(64.0,flushprocess);
    printf("download 64.0mb done\n");
    uploadload(500.0, flushprocess);
    return 0;
}

这个设计的关键点在于:

进阶优化思路

基于现有代码,我们可以进一步优化:

下面是一个增加颜色支持的示例代码:

// 添加颜色支持的进度条函数
void flushprocesscolor(const char *tips, double total, double current)
{
    const char *lable = "|/-\\";
    int len = strlen(lable);
    static int index = 0;
    char buffer[size];
    memset(buffer, 0, sizeof(buffer));

    double rate = current*100.0/total;
    int num = (int)rate;

    int i = 0;
    for(; i < num; i++)
        buffer[i] = style;

    // 根据进度设置不同颜色
    const char *color = "\033[0;32m"; // 默认绿色
    if(rate < 30.0) color = "\033[0;31m"; // 红色
    else if(rate < 70.0) color = "\033[0;33m"; // 黄色
    
    printf("%s%s...[%-100s][%.1lf%%][%c]\033[0m\r", color, tips, buffer, rate, lable[index++]);
    fflush(stdout);
    index %= len;

    if(num >= 100)printf("\n");
}

总结

通过这个简单的进度条程序,我们学习了:

进度条虽然看似简单,但涉及到了界面设计、算法优化和系统交互等多个方面的知识。在实际开发中,我们可以根据需求进一步扩展这个基础框架,实现更复杂、更美观的进度展示功能。

到此这篇关于linux在命令行环境中实现进度条的原理解析的文章就介绍到这了,更多相关linux命令行进度条内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

Nginx首页修改及使用Nginx实现端口转发

10-16

VNC连接Linux服务器蓝屏的解决方法

10-16

nginx下各种超时时间的配置详细指南

10-16

centos8下安装nginx并修改其默认网页方式

10-16

Linux网络分析终极武器之Tcpdump深度指南

10-16

使用fcntl系统函数在Linux下改变文件属性的操作指南

10-15

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论