mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-11-04 00:02:21 +08:00
update:运行多文件同时下载
This commit is contained in:
parent
50c916a8cc
commit
73a3733bc1
@ -1,44 +1,62 @@
|
||||
#include "downloadmanager.h"
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include <QDebug>
|
||||
|
||||
DownloadManager::DownloadManager(QObject *parent) : QObject(parent) {}
|
||||
DownloadManager::DownloadManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
cleanupTempFiles();
|
||||
}
|
||||
|
||||
void DownloadManager::startDownload(const QString &packageName, const QString &url, const QString &outputPath)
|
||||
{
|
||||
if (m_processes.contains(packageName)) {
|
||||
qWarning() << packageName << " is already downloading.";
|
||||
return;
|
||||
}
|
||||
|
||||
QString metalinkUrl = url + ".metalink";
|
||||
QStringList arguments;
|
||||
arguments << "--enable-rpc=false"
|
||||
<< "--console-log-level=warn"
|
||||
<< "--summary-interval=1"
|
||||
<< "--dir=" + QFileInfo(outputPath).absolutePath()
|
||||
<< "--out=" + QFileInfo(outputPath).fileName()
|
||||
<< metalinkUrl;
|
||||
QFileInfo fileInfo(outputPath);
|
||||
|
||||
QStringList arguments = {
|
||||
"--enable-rpc=false",
|
||||
"--console-log-level=warn",
|
||||
"--summary-interval=1",
|
||||
"--allow-overwrite=true",
|
||||
"--dir=" + fileInfo.absolutePath(),
|
||||
"--out=" + fileInfo.fileName(),
|
||||
metalinkUrl
|
||||
};
|
||||
|
||||
QProcess *process = new QProcess(this);
|
||||
m_processes.insert(packageName, process);
|
||||
|
||||
// ✅ 改为按行读取(逐行处理)
|
||||
connect(process, &QProcess::readyReadStandardOutput, [this, process, packageName]() {
|
||||
connect(process, &QProcess::readyReadStandardOutput, this, [this, packageName, process]() {
|
||||
while (process->canReadLine()) {
|
||||
QString line = process->readLine().trimmed();
|
||||
QString line = QString::fromUtf8(process->readLine()).trimmed();
|
||||
QRegularExpression regex(R"(\((\d+)%\))");
|
||||
QRegularExpressionMatch match = regex.match(line);
|
||||
if (match.hasMatch()) {
|
||||
int progress = match.captured(1).toInt();
|
||||
emit downloadProgress(packageName, progress);
|
||||
qDebug() << "下载进度:" << progress << "%";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 下载完成
|
||||
connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
[this, packageName](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
bool success = (exitCode == 0 && exitStatus == QProcess::NormalExit);
|
||||
this, [this, packageName, outputPath](int exitCode, QProcess::ExitStatus status) {
|
||||
bool success = (exitCode == 0 && status == QProcess::NormalExit);
|
||||
if (!success) {
|
||||
qWarning() << "Download failed for" << packageName << "exit code:" << exitCode;
|
||||
}
|
||||
|
||||
removeAria2Files(outputPath); // 清理残留 .aria2
|
||||
emit downloadFinished(packageName, success);
|
||||
m_processes.remove(packageName);
|
||||
|
||||
QProcess *proc = m_processes.take(packageName);
|
||||
if (proc) proc->deleteLater();
|
||||
});
|
||||
|
||||
process->start("aria2c", arguments);
|
||||
@ -46,10 +64,35 @@ void DownloadManager::startDownload(const QString &packageName, const QString &u
|
||||
|
||||
void DownloadManager::cancelDownload(const QString &packageName)
|
||||
{
|
||||
if (m_processes.contains(packageName)) {
|
||||
QProcess *process = m_processes[packageName];
|
||||
process->terminate();
|
||||
process->waitForFinished();
|
||||
m_processes.remove(packageName);
|
||||
if (!m_processes.contains(packageName)) return;
|
||||
|
||||
QProcess *process = m_processes.take(packageName);
|
||||
if (process) {
|
||||
process->kill(); // 立即终止
|
||||
process->waitForFinished(3000); // 最多等待3秒
|
||||
process->deleteLater();
|
||||
}
|
||||
|
||||
emit downloadFinished(packageName, false); // 显式通知取消
|
||||
|
||||
}
|
||||
|
||||
void DownloadManager::removeAria2Files(const QString &filePath)
|
||||
{
|
||||
QString ariaFile = filePath + ".aria2";
|
||||
QFile::remove(ariaFile);
|
||||
}
|
||||
|
||||
bool DownloadManager::isDownloading(const QString &packageName) const
|
||||
{
|
||||
return m_processes.contains(packageName);
|
||||
}
|
||||
|
||||
void DownloadManager::cleanupTempFiles()
|
||||
{
|
||||
QDir tempDir(QDir::tempPath());
|
||||
QStringList leftovers = tempDir.entryList(QStringList() << "*.aria2", QDir::Files);
|
||||
for (const QString &f : leftovers) {
|
||||
tempDir.remove(f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,23 +2,26 @@
|
||||
#define DOWNLOADMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QMap>
|
||||
#include <QProcess>
|
||||
|
||||
class DownloadManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadManager(QObject *parent = nullptr);
|
||||
void startDownload(const QString &packageName, const QString &url, const QString &outputPath);
|
||||
void cancelDownload(const QString &packageName);
|
||||
bool isDownloading(const QString &packageName) const;
|
||||
|
||||
signals:
|
||||
void downloadProgress(const QString &packageName, int progress);
|
||||
void downloadFinished(const QString &packageName, bool success);
|
||||
|
||||
private:
|
||||
void cleanupTempFiles();
|
||||
void removeAria2Files(const QString &filePath);
|
||||
|
||||
QMap<QString, QProcess*> m_processes;
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user