You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.7 KiB
133 lines
4.7 KiB
#ifndef DOWNLOADER_H
|
|
#define DOWNLOADER_H
|
|
|
|
#include <QObject>
|
|
#include <QNetworkAccessManager>
|
|
#include <QNetworkReply>
|
|
#include <QUrl>
|
|
#include <QFile>
|
|
#include <QDir>
|
|
|
|
extern QString CHECK_URL;
|
|
|
|
class Downloader : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/**
|
|
* @brief 构造联网下载器。
|
|
* @param parent Qt 父对象,负责随父对象析构自动释放网络管理器。
|
|
*
|
|
* 设计意图:Downloader 只负责单文件下载和本地落盘,不直接操作界面。
|
|
* 网络请求、QFile 都运行在创建它的线程中,外部跨线程调用时应使用信号槽队列连接,
|
|
* 避免在其它线程直接读写 QFile 或 QNetworkReply。
|
|
*/
|
|
explicit Downloader(QObject *parent = nullptr);
|
|
|
|
/**
|
|
* @brief 设置默认下载地址。
|
|
* @param url 输入的远程文件 URL;为空或非法时不会主动下载。
|
|
*/
|
|
void setUrl(const QString &);
|
|
|
|
/**
|
|
* @brief 开始下载文件。
|
|
* @param url 可选下载地址;为空时使用 setUrl() 已保存的地址。
|
|
*
|
|
* 输出通过 doProgress/doFinished/onError/doShowInfo 信号返回。
|
|
* 边界条件:同一 Downloader 同时只允许一个请求;目标文件名为空或 URL 非法会直接报错。
|
|
* 资源风险:下载过程写入 .part 临时文件,成功后替换为目标文件名;异常时关闭文件并清理网络对象。
|
|
*/
|
|
void startDownload(const QString &url = QString());
|
|
|
|
/**
|
|
* @brief 触发版本检测请求。
|
|
*
|
|
* 当前接口保留兼容旧调用;版本检测结果由 QNetworkAccessManager::finished 处理。
|
|
*/
|
|
void checkVersion();
|
|
|
|
/**
|
|
* @brief 获取当前落盘文件对象。
|
|
* @return 下载完成后的 QFile 引用;调用方只应读取文件名/路径,不应在下载中修改其打开状态。
|
|
*/
|
|
const QFile &getFile() const;
|
|
|
|
/**
|
|
* @brief 获取下载目录。
|
|
* @return 应用程序目录;用于外部定位下载包。
|
|
*/
|
|
const QDir &getDir() const;
|
|
|
|
/**
|
|
* @brief 获取目标文件名。
|
|
* @return 不包含目录的本地文件名。
|
|
*/
|
|
const QString &fileName() const;
|
|
|
|
/**
|
|
* @brief 设置目标文件名。
|
|
* @param newFileName 不包含路径的文件名,避免远程响应头异常覆盖任意目录。
|
|
*/
|
|
void setFileName(const QString &newFileName);
|
|
|
|
public slots:
|
|
|
|
signals:
|
|
/** @brief 下载进度,received/total 单位为字节;total 为 -1 时表示服务器未给出总长度。 */
|
|
void doProgress(qint64, qint64);
|
|
|
|
/** @brief 网络错误通知;错误发生后 Downloader 会关闭文件并释放 reply。 */
|
|
void onError(QNetworkReply::NetworkError);
|
|
|
|
/** @brief 下载完成通知;仅在网络无错误且临时文件成功改名后发出。 */
|
|
void doFinished();
|
|
|
|
/** @brief 文本状态通知,用于把边界条件、文件错误等信息显示到界面。 */
|
|
void doShowInfo(const QString&);
|
|
|
|
private:
|
|
/**
|
|
* @brief 关闭当前请求并释放 QNetworkReply。
|
|
* @param removePartial 为 true 时删除 .part 临时文件,常用于错误/取消场景。
|
|
*
|
|
* 设计意图:统一网络对象和文件句柄的释放路径,避免 finished/error 分支重复清理导致二次关闭。
|
|
*/
|
|
void cleanupCurrentReply(bool removePartial);
|
|
|
|
/**
|
|
* @brief 计算临时下载文件的完整路径。
|
|
* @return 当前目标文件名对应的 .part 路径;文件名为空时返回空字符串。
|
|
*/
|
|
QString partialFilePath() const;
|
|
|
|
/**
|
|
* @brief 计算最终下载文件的完整路径。
|
|
* @return 当前目标文件名对应的最终路径;文件名为空时返回空字符串。
|
|
*/
|
|
QString targetFilePath() const;
|
|
|
|
/** @brief 网络访问管理器,归 Downloader 父子对象树管理,必须在同一线程使用。 */
|
|
QNetworkAccessManager *m_pNetWorkAccessManager{nullptr};
|
|
|
|
/** @brief 当前下载响应对象,finished 后通过 deleteLater 释放,避免悬空回调。 */
|
|
QNetworkReply *m_pReply{nullptr};
|
|
|
|
/** @brief 正在下载标识,防止重复点击造成多个请求同时写同一个文件。 */
|
|
bool m_bIsDownloading = false;
|
|
|
|
/** @brief 当前下载 URL;startDownload 允许临时覆盖该地址。 */
|
|
QUrl m_pUrl{};
|
|
|
|
/** @brief 本地目标文件名,仅保存文件名不保存目录,避免路径注入。 */
|
|
QString m_fileName = "";
|
|
|
|
/** @brief 下载落盘文件句柄,下载中指向 .part 文件,完成后指向正式文件。 */
|
|
QFile file;
|
|
|
|
/** @brief 下载目录,默认应用程序目录;目录不存在时 startDownload 会创建。 */
|
|
QDir dir;
|
|
|
|
};
|
|
|
|
#endif // DOWNLOADER_H
|
|
|