QT案例 使用QProcess调用Aria2.exe下载网络资源文件

概要

QT案例-测试Qt调用Aria2.exe下载速度的稳定性优劣笔记。

整体架构流程

使用QProcess调用Aria2.exe下载网络资源文件,
解析Aria2.exe输出到控制台的如上格式的文本内容,
获取下载速度,下载倒计时,下载进度等。

技术名词解释

aria2 是一个下载文件的实用程序。支持的协议有HTTP(S)、FTP、SFTP、BitTorrent和Metalink。aria2可以从多个来源/协议下载文件,并尝试利用您的最大下载带宽。它支持同时从HTTP(S)/FTP /SFTP和BitTorrent下载一个文件,而从HTTP(S)/FTP/SFTP下载的数据则上传到BitTorrent swarm。aria2使用Metalink块校验和,在下载文件时自动验证数据块。
参考文档:

aria2.exe的常用的cmd调用命令在aria2 使用简介一文中已经介绍的很详细了,建议参考!
可通过CMD控制台执行: aria2.exe -v 输出参数说明

$ git clone https://github.com/aria2/aria2.git

技术细节

CMD命令行调用下载文件

使用QProcess执行CMD命令调用Aria2.exe下载https文件

  QString CmdStr="C:\\Users\\admin\\Desktop\\aria2c\\aria2c.exe" //exe路径
                     " \"http://XXXX/d/assistant.iso\"" //! _httpurl
                     " --dir=\"E:/JSYOS\""      //! 输出文件目录
                     " --continue=true"         //! 断点续传
                     " --out=\"ARIA2C_PE.iso\"" //! 输出文件名
                     " --file-allocation=none"   //! 不预分配空间
                     ;
    if(_Filename!="")
        CmdStr+= " --out=\""+_Filename+"\""; //! 指定输出文件名
    CmdStr+= " --max-tries=20";//! 失败重连次数
    CmdStr+= " --retry-wait=5"; //!失败重间隔时间(单位:秒)
     
    qDebug()<<"aria2 Start : "<<CmdStr;
    QProcess* process=new QProcess() ;
    process->start(CmdStr.toLocal8Bit());
    if (process->waitForStarted(-1)) {
        while(process->waitForReadyRead(-1)) {
            //qDebug()<<process->state()<<" "<<process->error();
            QString str=QString::fromLocal8Bit(process->readAllStandardOutput().data()).replace("\r\n","");
            //qDebug()<<"waitForReadyRead : "<<str;
            // 解析输入文本 regExpStr(str);
        }
    }
    process->waitForFinished(-1);
    process->close();

解析输出的文本内容获取下载进度

使用正则表达是匹配以下格式内容:
db92cc 23MiB/1.0GiB(2%) CN:1 DL:3.4MiB ETA:5m5s
db92cc 27MiB/1.0GiB(2%) CN:1 DL:3.5MiB ETA:4m59s
解析Aria2.exe输出到控制台的如上格式的文本内容,
获取下载速度,下载进度,倒计时,文件大小占比等内容。

void regExpStr(QString outputStr)
{
//    qDebug()<<endl;
    QRegExp regExp("\\[#([^\\]]*)\\]");
    int pos = regExp.indexIn(outputStr);
    if(regExp.captureCount()>=1)
    {
        QString Analysis=regExp.cap(1);
        if(Analysis.trimmed()!="")
        {
            qDebug()<<"----->"<<Analysis;
            QStringList listStr=Analysis.split(" ");
            for(int i=0;i<listStr.count();i++)
            {
                //! 下载速度
                if(listStr[i].mid(0,3).toUpper()=="DL:")
                {
					//qDebug()<<"[下载速度]: "<<listStr[i].mid(3,listStr[i].length()-3);
                    //! 下载速度 emit Down_Speed(listStr[i].mid(3,listStr[i].length()-3)+"/S");
                }
                if(listStr[i].mid(0,4).toUpper()=="ETA:")
                {
					//qDebug()<<"[剩余时间]: "<<listStr[i].mid(4,listStr[i].length()-4);
                    QString TimeStr=listStr[i].mid(4,listStr[i].length()-4).toLower();
                    QString H="00";
                    QString M="00";
                    QString S="00";
                    if(TimeStr.indexOf("h")!=-1)
                    {
                        H=TimeStr.mid(0,TimeStr.indexOf("h"));
                        TimeStr=TimeStr.mid(TimeStr.indexOf("h")+1,TimeStr.length()-TimeStr.indexOf("h")-1);
                    }
                    if(TimeStr.indexOf("m")!=-1)
                    {
                        M=TimeStr.mid(0,TimeStr.indexOf("m"));
                        TimeStr=TimeStr.mid(TimeStr.indexOf("m")+1,TimeStr.length()-TimeStr.indexOf("m")-1);
                    }
                    if(TimeStr.indexOf("s")!=-1)
                    {
                        S=TimeStr.mid(0,TimeStr.indexOf("s"));
                        TimeStr=TimeStr.mid(TimeStr.indexOf("s")+1,TimeStr.length()-TimeStr.indexOf("s")-1);
                    }
                    QString timeleft=QString("%1:%2:%3")
                                           .arg(H.toInt(),2,10,QLatin1Char('0'))
                                           .arg(M.toInt(),2,10,QLatin1Char('0'))
                                           .arg(S.toInt(),2,10,QLatin1Char('0'));
                    qDebug()<<"[剩余时间]: "<<timeleft;

                    //! 倒计时 emit Time_Remaining(timeleft);

                }
                if(listStr[i].indexOf('/')!=-1 && listStr[i].indexOf('%')!=-1 )
                {
                    int underline=listStr[i].indexOf('/');
                    QString transfered=listStr[i].mid(0,underline);
                    int leftbracket=listStr[i].indexOf('(');
                    int rightbracket=listStr[i].indexOf(')');
                    QString total=listStr[i].mid(underline+1,leftbracket-underline-1);
                    QString percentum=listStr[i].mid(leftbracket+1,3).replace("%","").replace(")","");
                    qDebug()<<"[已下载]: "<<transfered;
                    qDebug()<<"[总大小]: "<<total;
                    qDebug()<<"[百分比]: "<<percentum;
                   //! 下载进度条 emit ProgressBar(percentum.toInt());
                   //! 文件占比 emit SendDownsize(transfered,total);

                }
            }
        }
    }

}

输出内容:

-----> "db92cc 4.4MiB/1.0GiB(0%) CN:1 DL:4.9MiB ETA:3m38s"
[已下载]:  "4.4MiB"
[总大小]:  "1.0GiB"
[百分比]:  "0"
[剩余时间]:  "00:03:38"
-----> "db92cc 9.5MiB/1.0GiB(0%) CN:1 DL:5.0MiB ETA:3m33s"
[已下载]:  "9.5MiB"
[总大小]:  "1.0GiB"
[百分比]:  "0"
[剩余时间]:  "00:03:33"
-----> "db92cc 12MiB/1.0GiB(1%) CN:1 DL:4.2MiB ETA:4m10s"
[已下载]:  "12MiB"
[总大小]:  "1.0GiB"
[百分比]:  "1"
[剩余时间]:  "00:04:10"

Aria2源码不支持mingw直接编译(文言一心)

Aria2.exe也有libaria2这个C++库接口的,但是默认编译不生成,而且Aria2源码不支持mingw直接编译,建议使用Cygwin
Aria2是一个轻量级多协议和多源命令行下载工具,它使用了一些特定于Linux系统的编译工具和库,如gcc。而MinGW(Minimalist GNU for Windows)是一个Windows平台下的GNU工具集,它提供了一套类似于Linux下的编译环境。由于Aria2是为Linux环境设计的,其源代码可能包含对特定Linux环境的调用和依赖,这些调用和依赖在Windows下的MinGW环境中不适用。因此,直接使用MinGW来编译Aria2可能会失败,因为编译器找不到相关的头文件或者库。
解决方法:

  • 使用Cygwin:Cygwin是一个在Windows平台上运行的类UNIX环境,它提供了一套类似于Linux的命令行工具和库。用户可以在Cygwin环境中编译Aria2。
  • 使用WSL(Windows Subsystem for Linux):从Windows 10开始,微软提供了WSL,允许用户在Windows上原生运行Linux环境。在WSL中可以直接编译Aria2。
  • 使用Docker:Docker可以创建一个隔离的容器,在容器中可以运行Linux环境,并且在容器内编译Aria2。
  • 使用Linux虚拟机:在Windows上安装一个Linux虚拟机,并在虚拟机中编译Aria2。
    建议选择最适合自己需求和环境的解决方案进行操作,可参考:
    aria2的libaria2在windows使用的资料搜集

小结

QT本身是能通过QNetworkRequestQNetworkReplyQNetworkAccessManager实现文件下载的功能,但是下载的速度不是太快,也并不稳定,
而通过调用Aria2.exe下载,可以设置多个下载进程,速度更快,而且适用于下载多种格式文件包括不限于 HTTP(S)FTPSFTPBitTorrentMetalink 等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

得鹿梦鱼、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值