QtDownloadTool——简单的HTTP资源下载工具

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q294971352/article/details/78534319

闲话

之前想着迅雷9那广告满天的界面,简直被恶心到了,就想着自己写个下载工具,结果花几个小时写好(copy好别人的代码),发现还是TM迅雷下载着舒服,毕竟人家那这么多年的P2P技术不是摆设,自己也只是写着玩玩儿,学习学习而已。程序运行图如下:
这里写图片描述

资源获取

要下载文件之前,当然要获取到资源文件,才可以开始下载,Qt实现了一个简单的资源获取方法:

/* 通过url获取文件名 */
QString Network::getFileInfo(QString task)
{
    QUrl url = QUrl::fromEncoded(task.toLocal8Bit());
    QString path = url.path();
    QString fileName = QFileInfo(path).fileName();

    return fileName;
}

在我们的面前就是传个url的path到QFileInfo类中,然后就可以返回资源名,很简单,当然只能获取简单的资源文件,要是像什么度娘上的图片或者度盘的链接,是识别不出来的。之前也看过别人的博客说可以先发http请求获取,不过自己没试过,也不知道是否可行。

开始下载

既然是一个HTTP资源下载工具,当然需要设计到HTTP请求,这里的请求很简单,其实也就是设置一下HTTP请求头而已:

QNetworkRequest request(url);

request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
request.setRawHeader("Range", QString("bytes=%1-").arg(currentFileSize).toLatin1());

第一个请求头,产生请求的浏览器类型;
第二个请求头,接收文件的位置和范围。这个请求是最关键的,用来实现断点续传。

设置好请求头后,只需要连接几个接收的槽函数,就可以开始接收文件了:

reply = manager.get(request);

connect(reply, SIGNAL(readyRead()), this, SLOT(readyToRead()));
connect(reply, SIGNAL(finished()),  this, SLOT(downloadFinished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
        this, SLOT(downloadProgress(qint64,qint64)));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
        this, SLOT(downloadError(QNetworkReply::NetworkError)));

这几个槽的意思就很清楚了:
第一个,数据准备好,等着我们去读了;
第二个,文件接收完成;
第三个,接收的进度;
第四个,接收过程中发生的错误。

读函数,只需要往文件里写就对了:

void Network::readyToRead()
{
    /* write data to file */
    file.write(reply->readAll());
}

错误处理,这里我就只把错误打印出来,把下载停了就完事儿了,没做过多处理:

void Network::downloadError(QNetworkReply::NetworkError code)
{
    qDebug() << "Failed: " << code;

    stopTask(currentTask);
}

接收完成,向界面发送消息,同时把任务从下载列表中删除掉,如果任务队列不为空就开始下一个任务:

void Network::downloadFinished()
{
    file.close();

    timeElapsed = 0;

    isDownloading = false;

    downloadList.removeOne(currentTask);

    if (reply->error()) {
        qDebug() << "Failed: " << reply->errorString();
        return ;
    }

    reply->deleteLater();

    emit taskFinished(currentTask);

    if (!downloadList.isEmpty()) {
        QString taskNext = downloadList.first();
        startDownload(taskNext, downloadPath);
    }
}

从上面可以看出,这里也打印了错误信息,因为当发生错误,传输中断后,也会接收到finished()信号。

下载进度,在这可以获取下载到的文件大小,然后自己也可以实现速度计算:

void Network::downloadProgress(qint64 bytesReceived, qint64 byteTotal)
{
    double speed = (bytesReceived * 1000.0) / (downloadTime.elapsed() + timeElapsed);
    timeLast  = downloadTime.elapsed();

//    qDebug() << "Time elapse:" << downloadTime.elapsed() + timeElapsed;

    double percent = (bytesReceived + currentFileSize) * 100.0 / (byteTotal + currentFileSize);
    if (percent >= 100.0) {
        downloadFinished();
        return ;
    }

    emit process(currentTask, byteTotal + currentFileSize, percent, speed);
}

需要注意的是,如果是断点续传,这里获取到的byteTotal是还未接收的数据大小,所以需要把之前下载大小保存起来,当然也可以通过读已写文件大小来获取。

至于界面什么的,就不说了,不得不承认自己没有一点艺术细胞,代码下载地址:
https://github.com/DragonPang/QTDownloadTool

猜你喜欢

转载自blog.csdn.net/q294971352/article/details/78534319
今日推荐