2017-09-13 3 views
0

J'ai utilisé une classe DownloadManager comme ça, mais le problème est que pour les fichiers volumineux, j'ai une mauvaise taille de 65536 Ko au lieu de 51328022 octets. Il y a quelque chose qui ne va pas dans la méthode saveDisk.La taille du fichier est erronée dans Qt 5.6

ps: J'utilise Qt 5.6 cuz je dois exécuter l'application sous 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(); 
    } 
} 
+0

Vous ne tentez même pas vérifier si 'file.write' a écrit toutes les données. Lisez ce que font les fonctions et ce que signifient leurs valeurs de retour. – nwp

Répondre

0

Il est D'accord. Je l'ai remplacé cette ligne:

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

par

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; 

je l'ai écrit plusieurs morceaux au lieu d'un grand

0

Vous devez appeler DownloadManager :: SaveToDisk par le signal QNetworkReply :: readyRead

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

void DownloadManager::saveToDisk(QNetworkReply* reply) 
{ 
    ... 
    file.write(reply->read(reply_->bytesAvailable())); 
    ... 
}