LINUX.ORG.RU

Как загружать несколько файлов сразу через QNetworkReply и QNetworkAccessManager

 ,


0

1

Доброго времени суток. задача такая, нужно мне скачать сразу несколько файлов как я это делаю:

    QNetworkAccessManager* pmanager = new QNetworkAccessManager(this);
    pmanager->get(QNetworkRequest(url));
    connect(pmanager,SIGNAL(finished(QNetworkReply*)),this,SLOT(FinishDownload(QNetworkReply*)));
FinishDownload:
void Download_window::FinishDownload(QNetworkReply *replay){
    QString way = wayfile;
    if(replay->error() == QNetworkReply::NoError){
        QByteArray data = replay->readAll();
        QFile file(way);
        if(file.open(QIODevice::WriteOnly)){
            file.write(data);
            replay->deleteLater();
            file.close();
        }
    }
}
Когда я добавляю в загрузку к примеру 2 файла то по окончанию загрузки сохраняется только последний файл, то есть второй. Что делать? подскажите новичку.

Сорян, если что не так — пиво пью сейчас. В свой класс добавь структурку, чтобы различать файлы

struct Download
{
    QString destFileName;
    QFile destination;
};
QHash<QNetworkReply *, Download *> downloads;
Ну и качай типа так
void Downloader::download(const QUrl &url, const QString &dest) {
    auto download = new Download();
    download->destFileName = dest;
    static const QString incompleteSuffix(".part");
    download->destination.setFileName(download->destFileName + incompleteSuffix);
    if (!download->destination.open(QIODevice::WriteOnly)) {
        qWarning() << "Cannot open file to write " << download->destination.fileName();
        delete download;
        onDownloadError(url);
        return;
    }
    QNetworkRequest request(url);
    
    QNetworkReply *reply = accessManager.get(request);
    downloads.insert(reply, download);
    // Reply
    QObject::connect(reply, &QNetworkReply::readyRead, [this, reply]() {
        if (!downloads.contains(reply)) {
            qWarning() << "Unknown download";
            return;
        }
        static QByteArray buffer(16384, '\0');
        Download *d = downloads.value(reply);
        while (reply->bytesAvailable()) {
            const qint64 read = reply->read(buffer.data(), buffer.size());
            qint64 written = 0;
            while (written < read) {
                const qint64 numWritten
                    = d->destination.write(buffer.data() + written, read - written);
                if (numWritten < 0) {
                    qCritical() << QString("Cannot download %1. Writing to file \"%2\" failed: %3")
                                       .arg(reply->url().toString(), d->destFileName,
                                           d->destination.errorString());
                    reply->disconnect();
                    onDownloadError(reply->url());
                    d->destination.close();
                    downloads.remove(reply);
                    reply->deleteLater();
                    return;
                }
                written += numWritten;
            }
        }
    });
    QObject::connect(reply, &QNetworkReply::finished, [this, reply]() {
        if (reply->error() == QNetworkReply::NoError) {
            if (downloads.contains(reply)) {
                Download *dl = downloads.value(reply);
                dl->destination.close();
                dl->destination.rename(dl->destFileName);
                downloads.remove(reply);
                delete dl;
            }
        }
        reply->deleteLater();
    });
    void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) = &QNetworkReply::error;
    QObject::connect(
        reply, errorSignal, [this, reply](QNetworkReply::NetworkError errorCode) {
            Q_UNUSED(errorCode);
            onDownloadError(reply->url());
        });
}

fluorite ★★★★★ ()

Не пользуйся сигналом finished у QNetworkAccessManager, это почти всегда приводит к плохому коду. Используй QNetworkReply::finished, к каждому реплаю приконнекть свой экземпляр объекта-обработчика

annulen ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.