使用Qt进行Http download时,需注意一点,安卓下载URL为https时会报错,需要支持SSL。
头文件downfile.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #ifndef DOWNFILE_H #define DOWNFILE_H
#include <QFile> #include <QtNetwork/QNetworkAccessManager> #include <QNetworkReply> #include <QMutex> #include <QSharedPointer>
#pragma pack(1)
struct UPDATE_HEADER { uint16_t project_id; uint8_t root_version; uint8_t stack_version; uint32_t app_version; uint32_t code_size; uint32_t crc32; } ;
struct pk_t { uint32_t addr; uint16_t pk; }; #pragma pack()
extern pk_t pt; extern UPDATE_HEADER ota_vs_info;
class DownFile : public QObject { Q_OBJECT public: static DownFile *getInstance(); private: DownFile(); DownFile& operator=(DownFile&) = delete; DownFile(DownFile&) = delete;
private: static DownFile *downFile; static QMutex m_mutex; private: QFile *avatorFile; QNetworkReply *avatorReply; QNetworkAccessManager *avatorManager;
public: int ota_size; uint8_t ota_data[40*1024]; private: QString fileName; QString downUrl = "http://qzwjer.top/doc/"; private: void copyfile();
private slots: void httpDownload(); void httpDownloadFinished();
public: void setUrl(const QString &); QString& getUrl(); void setFileName(const QString &); void getfile();
signals: void downComplete(); };
#endif
|
downfile.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
| #include "downfile.h" #include <QDebug> #include <QDataStream> #include <QFileInfo> #include <QDir> #include <QUrl>
#pragma execution_character_set("utf-8")
pk_t pt = {0}; UPDATE_HEADER ota_vs_info = {0};
#ifdef Q_OS_ANDROID static QString path = "file:///storage/emulated/0/BMTest/otafile/"; static QString fpath = QUrl(path).toLocalFile(); #else static QString fpath = "otafile/"; #endif
DownFile* DownFile::downFile = nullptr; QMutex DownFile::m_mutex;
DownFile *DownFile::getInstance() { if(nullptr == downFile){ m_mutex.lock(); if(nullptr == downFile){ downFile = new DownFile; } m_mutex.unlock(); } return downFile; }
DownFile::DownFile() { qDebug()<<fpath; }
void DownFile::copyfile() { QFile file(fpath + fileName); if(!file.open(QIODevice::ReadOnly)) { qDebug()<<"file open error!"; } else { memset(ota_data, 0, sizeof(ota_data)); ota_size = file.size(); QDataStream in(&file); while(!in.atEnd()) { in.readRawData((char*)ota_data, sizeof(ota_data)); }
#if 1 QString str; for(int i = 0; i < 16; i++) { str += QString::asprintf("%02x ", ota_data[i]); } qDebug()<<"ota_head:"<<str; #endif
memcpy(&ota_vs_info, ota_data, sizeof(UPDATE_HEADER)); emit downComplete(); } }
void DownFile::httpDownload() { #ifdef Q_OS_ANDROID QByteArray ba = avatorReply->readAll(); memcpy(&ota_data[ota_size], ba.data(), ba.length()); ota_size += ba.length(); #else #if 1 if(avatorFile){ avatorFile->write(avatorReply->readAll()); } #else QTextStream out(avatorFile); out<<avatorReply->readAll(); #endif #endif }
void DownFile::httpDownloadFinished() { #ifndef Q_OS_ANDROID avatorFile->flush(); avatorFile->close(); delete avatorFile; avatorFile=0; #endif qDebug()<<avatorReply->error(); if(avatorReply->error() != QNetworkReply::NoError) { qDebug()<<"download failed"; } else { qDebug()<<"download finished"; #ifndef Q_OS_ANDROID copyfile(); #else memcpy(&ota_vs_info, ota_data, sizeof(UPDATE_HEADER)); emit downComplete(); #endif } delete avatorManager; avatorManager = nullptr; }
void DownFile::setUrl(const QString &url) { downUrl = url; }
QString &DownFile::getUrl() { return downUrl; }
void DownFile::setFileName(const QString &name) { fileName = name; }
void DownFile::getfile() { QDir dir; bool ota_down_flag = false; ota_size = 0; #ifndef Q_OS_ANDROID QString ota_file = fpath + fileName; QFileInfo fileInfo(ota_file); if(fileInfo.isFile()) { ota_down_flag = true; qDebug()<<"本地文件"; copyfile(); } else if(!dir.exists(fpath)) { dir.mkpath(fpath); } #endif if(!ota_down_flag) { #ifndef Q_OS_ANDROID avatorFile = new QFile(ota_file); if(!avatorFile->open(QIODevice::WriteOnly)) { delete avatorFile; avatorFile=0; qDebug()<<"can not write ota file"; return; } #endif qDebug()<<downUrl + fileName; QUrl serviceUrl = QUrl(downUrl + fileName); avatorManager = new QNetworkAccessManager(this); avatorReply=avatorManager->get(QNetworkRequest(serviceUrl)); connect(avatorReply,SIGNAL(readyRead()),this,SLOT(httpDownload())); connect(avatorReply,SIGNAL(finished()),this,SLOT(httpDownloadFinished())); } }
|