QT学习笔记(四):Http下载的另一种实现方式,使用QNetworkAccessManager
来源:互联网 发布:数据录入员累不累 编辑:程序博客网 时间:2024/06/11 00:40
分类: C/C++
下面是利用QNetworkAccessManager 和 QNetworkReply 实现的一个http下载类,由于QNetworkAccessManager里面没有提供网络连接中断和超时的错误处理,所以中间我用了QTimer来进行这个容错处理。
下面代码里,如果发现在下载过程中网络中断,我将重新下载 所有文件 ,并且永不停悉。(maybe it's not used for u, u can comment that).
Head file:
#ifndef IHTTPDOWNLOADS_H
#define IHTTPDOWNLOADS_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QFile>
#include <QNetworkReply>
#include <QTimer>
#include <QProgressBar>
class iHttpDownloadS : public QObject
{
Q_OBJECT
public:
explicit iHttpDownloadS(QObject *parent = 0, QProgressBar *_progressBar = 0);
~iHttpDownloadS();
bool getFileFromURL(const QUrl &url, const QString &filePath); /* get file from url which we need to download, and restore to filePath */
const QString &getLastErrorMessage(); /* if error occurs, use this to get the error message */
void setErrorMessage(const QString &msg); /* set _errMsg */
signals:
public slots:
void replyFinished(QNetworkReply*); /* download finished */
void replayDownloadProgress(qint64, qint64); /* downloading... */
void slotError(QNetworkReply::NetworkError); /* handle error */
void slotReadyRead();/* ready read */
void handleTimeOut(); /* handle time out */
private:
QNetworkAccessManager *_downloadManager;
QNetworkReply *_reply;
QString _errMsg;
QFile _file;
QProgressBar *_progressBar;
QTimer *_timeOut;
QString _filePath;
QUrl _url;
};
#endif // IHTTPDOWNLOADS_H
Implementation file:
#include "ihttpdownloads.h"
#include <QDebug>
iHttpDownloadS::iHttpDownloadS(QObject *parent, QProgressBar *bar) :
QObject(parent), _progressBar(bar)
{
_downloadManager = new QNetworkAccessManager(this);
_timeOut = new QTimer(this);
connect(_downloadManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
connect(_timeOut, SIGNAL(timeout()), this, SLOT(handleTimeOut()));
}
iHttpDownloadS::~iHttpDownloadS()
{
_reply->deleteLater();
_downloadManager->deleteLater();
}
bool iHttpDownloadS::getFileFromURL(const QUrl &url, const QString &filePath) /* get file from url which we need to download, and restore to filePath */
{
/* confirm the url is valid or not */
if (!url.isValid())
{
setErrorMessage(QString("Error:URL has specify a invalid name."));
return false;
}
if (url.scheme() != "http")
{
setErrorMessage(QString("Error:URL must start with 'http:'"));
return false;
}
if (url.path().isEmpty())
{
setErrorMessage(QString("Error:URL's path is empty."));
return false;
}
if (filePath.isEmpty())
{
setErrorMessage(QString("Error:invalid filePath."));
return false;
}
_file.setFileName(filePath);
if (!_file.open(QIODevice::WriteOnly))
{
setErrorMessage(QString("Error:Cannot open file."));
return false;
}
_url = url;
_filePath = filePath;
_reply = _downloadManager->get(QNetworkRequest(url));
connect(_reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
connect(_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(replayDownloadProgress(qint64, qint64)));
connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError)));
return true;
}
const QString &iHttpDownloadS::getLastErrorMessage()
{
return _errMsg;
}
void iHttpDownloadS::setErrorMessage(const QString &msg)
{
qDebug()<<msg;
_errMsg = msg;
}
/* slots */
void iHttpDownloadS::handleTimeOut()
{
qDebug()<<"time out..";
_timeOut->stop();
if (_file.isOpen())
{
_file.close();
}
getFileFromURL(_url, _filePath); /* try again */
}
void iHttpDownloadS::replyFinished(QNetworkReply* reply) /* download finished */
{
_file.waitForBytesWritten(10000);/* wait 10s for write to file complete, can comment this */
if (0 == _file.size())
{
qDebug()<<"Nothing be downloaded.";
}
else
{
/* add our updateUI code here... */
qDebug()<<"finished";
}
}
void iHttpDownloadS::replayDownloadProgress(qint64 done, qint64 total) /* downloading... */
{
qDebug()<<QString("%1%").arg(done / (double)total * 100);
if ((0 != _progressBar) && (0 != total))
{
_progressBar->setMaximum(total);
_progressBar->setValue(done);
}
}
void iHttpDownloadS::slotReadyRead() /* if this is not been fired for 30s, we trate this timeout, and the timout handle will re download the file */
{
_file.write(this->_reply->readAll());
if (_timeOut->isActive())
{
_timeOut->stop();
}
_timeOut->start(30000);/* wait 30 seconds */
}
void iHttpDownloadS::slotError(QNetworkReply::NetworkError errorCode) /* handle error */
{
qDebug()<<"error:"<<errorCode;
setErrorMessage(QString("Error:NetworkError code:%1").arg(errorCode));
if (_file.isOpen())
{
_file.close();
}
getFileFromURL(_url, _filePath);/* try again */
}
这里就不作过多解释了,因为很简单,yes?
- QT学习笔记(四):Http下载的另一种实现方式,使用QNetworkAccessManager
- Http下载的另一种实现方式,使用QNetworkAccessManager
- Qt通过QNetworkAccessManager实现Http get方法文件下载
- Qt通过QNetworkAccessManager实现Http get方法文件下载
- 关于Qt使用QNetworkAccessManager下载文件(实现断点续传功能)
- 关于Qt使用QNetworkAccessManager下载文件(实现断点续传功能)
- QT之 QNetworkAccessManager学习笔记
- Qt通过QNetworkAccessManager实现Http网络通信
- Qt通过QNetworkAccessManager实现Http网络通信
- QT利用QNetworkAccessManager下载文件
- QNetworkAccessManager学习笔记
- qt 的QNetworkAccessManager的使用和防止内存泄漏
- 【程序员一枚】Qt网络开发之QNetworkAccessManager的使用
- 程序员一枚】Qt网络开发之QNetworkAccessManager的使用
- QT 5使用QNetworkAccessManager类遇到的问题
- 现代OpenGL+Qt学习笔记之四:使用Uniform变量实现对模型的旋转
- Decorator的另一种实现方式
- 代理的另一种实现方式
- 如何利用socket进行HTTP访问
- HDOJ 1201-18岁生日
- dbhome
- IOS8 设置TableView Separatorinset 分割线从边框顶端开始
- 常用的Linux网络配置命令
- QT学习笔记(四):Http下载的另一种实现方式,使用QNetworkAccessManager
- 在应用中更新App版本
- 数据库性能优化之SQL语句优化
- oracle中的define,declare,variable的区别
- GreenPlum体系架构
- Class.forName()用法及与new区别 详解
- nginx 正向代理和反向代理
- “京算盘”家庭理财软件开发日志(一) 项目立项
- AsyncTask