Http下载的另一种实现方式,使用QNetworkAccessManager

QNetworkRequest request(serviceUrl); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); networkManager->post(request, postData.encodedQuery());//HTTP Post请求部分包头 T assistant 中有关QHttp的说明,建议我们使用 QNetworkAccessManager 和 QNetworkReply 而非QHttp,因为前者的API更多,并且提供了更丰富的错误处理。     下面是利用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 */ }

你可能感兴趣的:(Http下载的另一种实现方式,使用QNetworkAccessManager)