代码:
#include "HttpDownload.h"
HttpDownload::HttpDownload()
{
downloadInfoList = new QLinkedList<HttpDownloadInfo>;
bDownloading = false;
thread = new QThread();
this->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), this, SLOT(handleThreadStarted()));
httpStream = NULL;
thread->start();
}
HttpDownload::~HttpDownload()
{
if(thread)
{
thread->quit();
thread->wait(100);
delete thread;
thread = 0;
}
delete downloadInfoList;
}
QAtomicPointer<HttpDownload> HttpDownload::instance;
QMutex HttpDownload::instanceMutex;
HttpDownload *HttpDownload::getInstance()
{
// HttpDownloadDebug("getInstance!");
if (!instance)
{
instanceMutex.lock();
if (!instance)
{
HttpDownloadDebug("create instance!");
instance = new HttpDownload();
}
instanceMutex.unlock();
}
return instance;
}
void HttpDownload::destroy()
{
instanceMutex.lock();
if (instance)
{
delete instance;
instance = 0;
}
instanceMutex.unlock();
}
void HttpDownload::handleThreadStarted()
{
startTimer(25);
thread->setObjectName("httpDownloadThread-"+ QString::number((int)QThread::currentThreadId()));
}
void HttpDownload::timerEvent(QTimerEvent *event)
{
// HttpDownloadDebug("onTimerEvent! thread name is: %s", QThread::currentThread()->objectName().toUtf8().data());
if (bDownloading)
{
return;
}
if (downloadInfoList->count() == 0)
{
return;
}
bDownloading = true;
currentDownloadInfo = downloadInfoList->takeFirst();
QString cacheFilePath = currentDownloadInfo.cacheFilePath;
if (cacheFilePath != NULL)
{
QFile::remove(cacheFilePath);
HttpDownloadDebug("file removed! %s", cacheFilePath.toUtf8().data());
}
QUrl url = currentDownloadInfo.url;
HttpDownloadDebug("start new download process, url is: %s", url.toString().toUtf8().data());
if (!httpStream)
{
httpStream = new QNetworkAccessManager();
// QObject::connect(QThread::currentThread(), SIGNAL(finished()), httpStream, SLOT(deleteLater()));
}
httpReply = httpStream->get(QNetworkRequest(url));
connect(httpReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(handleHttpProgress(qint64, qint64)));
connect(httpReply, SIGNAL(finished()), this, SLOT(handleHttpDone()));
connect(httpReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(handleHttpError(QNetworkReply::NetworkError)));
}
void HttpDownload::handleHttpProgress(qint64 bytesRead, qint64 totalBytes)
{
if (currentDownloadInfo.fileSize == 0)
{
QVariant var = httpReply->header(QNetworkRequest::ContentLengthHeader);
currentDownloadInfo.fileSize = var.toLongLong();
HttpDownloadDebug("file size is: %d", currentDownloadInfo.fileSize);
emit onFileSize(currentDownloadInfo.keyword, currentDownloadInfo.fileSize);
}
QByteArray data = httpReply->readAll();
HttpDownloadDebug("readLen is: %d", data.length());
currentDownloadInfo.allBytesRead += data.length();
HttpDownloadDebug("allBytesRead is: %d", currentDownloadInfo.allBytesRead);
QString cacheFilePath = currentDownloadInfo.cacheFilePath;
emit onProgress(currentDownloadInfo.keyword, data, currentDownloadInfo.allBytesRead);
HttpDownloadDebug("cacheFilePath is: %s", cacheFilePath.toUtf8().data());
}
void HttpDownload::handleHttpDone()
{
HttpDownloadDebug("downloading finished!");
httpReply->deleteLater();
emit onFinish(currentDownloadInfo.keyword, false,currentDownloadInfo.allBytesRead);
bDownloading = false;
}
void HttpDownload::handleHttpError(QNetworkReply::NetworkError errorCode)
{
HttpDownloadDebug("error is: %d", errorCode);
httpReply->deleteLater();
emit onFinish(currentDownloadInfo.keyword, true , 0);
bDownloading = false;
}
/*
* Interface
*/
bool HttpDownload::addRequest(QString keyword, const QUrl &url, const QString &cacheFilePath)
{
// HttpDownloadDebug("%s", QThread::currentThread()->objectName().toUtf8().data());
HttpDownloadDebug("keyword is: %s, url is: %s, cacheFilePath is: %s",
keyword.toUtf8().data(),
url.toString().toUtf8().data(),
cacheFilePath. toUtf8().data());
if (!url.isValid())
{
HttpDownloadDebug("Error:URL is invalid.");
return false;
}
if (url.scheme() != "http")
{
HttpDownloadDebug("Error:URL must start with 'http:'");
return false;
}
if (url.path().isEmpty())
{
HttpDownloadDebug("Error:URL's path is empty.");
return false;
}
int pos = cacheFilePath.lastIndexOf("/");
QString folderPath = cacheFilePath.left(pos + 1);
QDir *dir = new QDir;
if (!dir->exists(folderPath))
{
dir->mkpath(folderPath);
}
delete dir;
HttpDownloadInfo info;
info.keyword = keyword;
info.url = url;
info.cacheFilePath = cacheFilePath;
info.fileSize = 0;
info.allBytesRead = 0;
downloadInfoList->append(info);
return true;
}
2 个解决方案
#1
通过 QNetworkReply 打印 header 出来看看,也许是收到了 301/302之类的消息,需要手动处理的。
#2
好的,我加一下日志试试。
#1
通过 QNetworkReply 打印 header 出来看看,也许是收到了 301/302之类的消息,需要手动处理的。
#2
好的,我加一下日志试试。