前言
qt的QNetworkAccessManager get在下载文件时,当网络环境不确定行比较大时,比如网络断开等,往往需要程序实现断点续传的功能,好在qt帮我们做好了。下面看实现方法
如何实现?
用代码来回答。核心代码如下
#include
#include
#include
#include
#include
#include
class mDownload : public QObject {
Q_OBJECT
public:
mDownload (QObject *parent = nullptr);
~mDownload ();
Q_INVOKABLE void startDownload(const QString &url,
const QString &saveFilePath, bool bOverWrite);
signals:
void progressChanged(qreal progress);
void started();
void finished();
void update(int kiloBytesReceived, int kiloBytesTotal);
void error(int errorCode, QString errorString);
private slots:
void onReadyRead();
void onError(QNetworkReply::NetworkError ercode);
void onFinished();
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
private:
QNetworkAccessManager *_netManager;
QNetworkReply *_networkReply;
bool _bOverWrite; //下载模式是否是直接覆盖
qint64 _fileBeginSize; //记录开始下载的位置
};
void mDownload ::innerStartDownload() {
if (_running) {
if (_networkReply) {
if (_networkReply->isRunning()) _networkReply->abort();
shutdownNetworkReply();
shutdownSaveFile();
}
}
_fileBeginSize = 0;
if (_bOverWrite) {
_file = new QFile(_tmpDestination);
_file->open(QIODevice::WriteOnly);
} else {
_file = new QFile(_tmpDestination);
_fileBeginSize = _file->size();
_file->open(QIODevice::WriteOnly | QIODevice::Append);
}
QNetworkRequest request;
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setProtocol(QSsl::TlsV1_2);
config.setPeerVerifyMode(QSslSocket::VerifyNone);
request.setSslConfiguration(config);
request.setUrl(QUrl(_url));
QString strRange = QString("bytes=%1-").arg(_fileBeginSize);
request.setRawHeader("Range", strRange.toUtf8());
_networkReply = _netManager->get(request);
connectToNetworkReplySignals();
_lastReceiveDataTime = QDateTime::currentMSecsSinceEpoch();
_checkNetWorkTimer->start();
_progress = 0;
_tryDownloadTimes++;
setProgress(0.0);
_running = true;
}
核心代码如上,主要是下面两行来实现断点续传功能:
request.setUrl(QUrl(_url));
QString strRange = QString("bytes=%1-").arg(_fileBeginSize);
request.setRawHeader("Range", strRange.toUtf8());
_networkReply = _netManager->get(request);
总结
方便吧。