0

我使用了这样的 DownloadManager 类,但问题是对于大文件,我的大小错误为 65536KB 而不是 51328022 字节。saveDisk 方法有问题。

ps:我使用的是 Qt 5.6 因为我需要在 Windows Vista 和 XP 上运行该应用程序

bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
{
    LogManager* logmgr = LogManager::GetInstance();
    FileManager* filemgr = FileManager::GetInstance();

    QFileInfo fileinfo(filename);
    QString dirpath = fileinfo.absoluteDir().absolutePath();

    if (!filemgr->DirectoryIsPresent(dirpath))
    {
        if (!filemgr->CreateDirectory(dirpath)) {
            logmgr->Log(LOG_LEVEL_ERROR, QString("cannot create directory (") + dirpath + ")");
        }
    }

    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly)) {
        const QString errorText = QString("Could not open ") + filename + QString(" for writing:") + file.errorString();
        logmgr->Log(LOG_LEVEL_ERROR, errorText);
        return false;
    }

    file.write(data->readAll());
    file.close();

    return true;
}

void DownloadManager::downloadFinished(QNetworkReply *reply)
{
    LogManager* logmgr = LogManager::GetInstance();

    if (m_currentDownloads.contains(reply))
    {
        QUrl url = reply->url();
        if (reply->error() != QNetworkReply::NoError) {
            m_nbFailedDownload++;
            const QString errorText = QString("Download of ")+ url.toString() +" failed: " + reply->errorString() + " (" + QString::number(reply->error()) + ")";
            logmgr->Log(LOG_LEVEL_ERROR, errorText);
        } else {
            m_nbSucceededDownload++;
            QString filename = saveFileName(url);
            if (saveToDisk(filename, reply))
            {
                const QString infoText = QString("Download of ") + url.toString() + " succeeded (saved to " + filename + ")";
                logmgr->Log(LOG_LEVEL_INFO, infoText);
            }
        }

        m_currentDownloads.removeAll(reply);
        reply->deleteLater();
    }

    int total = m_nbTotalDownload == 0? 1:m_nbTotalDownload;
    emit onProgress((m_nbFailedDownload + m_nbSucceededDownload) * 100 / total);


    if (m_currentDownloads.isEmpty()){
        logmgr->Log(LOG_LEVEL_INFO, "DownloadManager downloads finished");
        emit onFinished();
    }
}
4

2 回答 2

0

没关系。我替换了这一行:

file.write(data->readAll());
file.close();
return true;

经过

ByteArray ba = data->readAll();
int nbTries = 99;
int n = ba.size();
int idx = 0;

while (n > 0 && nbTries > 0)
{
  int ret = file.write(ba.data() + idx, std::min(16*1024, n));
  if (ret > 0)
  {
      n -= ret;
      idx += ret;
  }
  else
  {
     nbTries --;
  }
}

file.close();
return nbTries > 0;

我写了几块而不是一大块

于 2017-09-15T10:15:31.333 回答
0

您应该通过信号 QNetworkReply::readyRead 调用 DownloadManager::saveToDisk

void DownloadManager::onDownloadReadyRead( QNetworkReply *reply )
{
    ...
    saveToDisk( filename, reply );
    ...
}

void DownloadManager::saveToDisk( QNetworkReply* reply )
{
    ...
    file.write( reply->read( reply_->bytesAvailable() ) );
    ...
}
于 2017-09-14T18:26:47.677 回答