这个问题很老,但我遇到了类似的问题,现在我有了 Qt 5.8 的解决方案。
代码旨在快速运行,网络请求以异步方式完成。因此,您必须为每个调用提供一个 ID,以了解哪个重放已完成。
此外,此代码使用 SSL。如果您不想使用 SSL 加密,请使用 QSslConfiguartion 删除 4 行。
文件下载器.h:
#ifndef FILEDOWNLOADER_H
#define FILEDOWNLOADER_H
#include <QObject>
#include <QStringList>
#include <QFile>
#include <QDir>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
class FileDownloader : public QObject
{
Q_OBJECT
public:
explicit FileDownloader(QObject *parent = 0);
virtual ~FileDownloader();
void downloadFile(QUrl url, QString id, QString dir_absolute_path);
signals:
// emits error string
void error(QString);
// Emits path to img on disk and id
void downloaded(QString, QString);
private slots:
void fileDownloaded();
void onReadyRead();
private:
QNetworkAccessManager *webCtrl;
QMap<QNetworkReply*, QFile*> replytofile;
QMap<QNetworkReply*, QPair<QString, QString> > replytopathid;
const QByteArray userAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36";
};
#endif // FILEDOWNLOADER_H
文件下载器.cpp:
#include "filedownloader.h"
#include <QDebug>
FileDownloader::FileDownloader(QObject *parent) :
QObject(parent),
webCtrl(new QNetworkAccessManager(this))
{
}
FileDownloader::~FileDownloader()
{
delete webCtrl;
}
void FileDownloader::downloadFile(QUrl url, QString id, QString dir_absolute_path)
{
QString url_string = url.toString();
QString path = dir_absolute_path + url_string.right(url_string.size() - url_string.lastIndexOf("/"));
QFile *file = new QFile(path, this);
if(!file->open(QIODevice::WriteOnly))
{
return;
}
QNetworkRequest request(url);
request.setRawHeader("User-Agent", userAgent);
QSslConfiguration sslConfiguration(QSslConfiguration::defaultConfiguration());
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
sslConfiguration.setProtocol(QSsl::AnyProtocol);
request.setSslConfiguration(sslConfiguration);
QNetworkReply *reply = webCtrl->get(request);
replytofile.insert(reply, file);
replytopathid.insert(reply, QPair<QString, QString>(path, id));
QObject::connect(reply, &QNetworkReply::finished, this, &FileDownloader::fileDownloaded);
QObject::connect(reply, &QNetworkReply::readyRead, this, &FileDownloader::onReadyRead);
}
void FileDownloader::fileDownloaded()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if (replytofile[reply]->isOpen())
{
replytofile[reply]->close();
replytofile[reply]->deleteLater();
}
switch(reply->error())
{
case QNetworkReply::NoError:
break;
default:
emit error(reply->errorString().toLatin1());
break;
}
emit downloaded(replytopathid[reply].first, replytopathid[reply].second);
replytofile.remove(reply);
replytopathid.remove(reply);
delete reply;
}
void FileDownloader::onReadyRead()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
replytofile[reply]->write(reply->readAll());
}