Я разрабатываю клиентское приложение, целью которого является загрузка некоторых файлов с веб-сервера, временное сохранение их в папке Temp, проверка целостности файлов, а затем отправка их на FTP-сервер в устройстве Embedded Linux.
Недавно у меня возникли проблемы при выполнении процесса на этапе предварительной разработки, когда я пытался выполнить загрузку с моего локального компьютера (см. соответствующий вопрос здесь). Теперь я могу загружать и загружать без ошибок и с проверкой (я использую QCryptographicHash + размер файла для проверки любых несоответствий) со своей машины, но этого не происходит, когда я пытаюсь загрузить с HTTP-сервера.
Всего загружается 8 файлов: три .tar.gz, один простой текст, две программы и два бинарника. Я могу успешно загрузить все сжатые файлы, текстовый файл и один из двоичных файлов, но другие, а именно две программы и один из двоичных файлов (образ ядра Linux), всегда загружаются неправильно.
Я проверяю это, замечая не только то, что хэш возвращает ошибку для них, но и их размеры: их размеры всегда неверны (и всегда одно и то же ошибочное значение при любой попытке загрузки). И файлы на сервере все правильные.
Мое первое подозрение заключалось в том, что мне нужно настроить загрузку по HTTP таким образом, чтобы он отличался от обычной загрузки по FTP с локальной машины, но я не знаю, как это будет. Более того, если эта дополнительная конфигурация была необходима, то почему некоторые файлы всегда возвращаются правильно?
Вот соответствующий код на данный момент:
void MainWindow::processNextDownload()
{
QUrl ulrTemp(updateData.at(transferStep).downloadUrl.arg(ui->leID->text())); //"//" +
if (updateData.at(transferStep).downloadUrl.contains("http"))
ulrTemp.setScheme("http");
else
ulrTemp.setScheme("file");
// ulrTemp.setUserName();
// ulrTemp.setPassword();
// ulrTemp.setPort();
qDebug() << "Downloading" << transferStep << "from" << ulrTemp;
#if 1
poReply = downloadNetworkManager->get(QNetworkRequest(ulrTemp));
#else
QNetworkRequest request;
request.setUrl(ulrTemp);
request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17");
poReply = downloadNetworkManager->get(request);
#endif
connect(poReply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(slotDownloadProgress(qint64,qint64)));
ui->statusBar->showMessage(tr("Downloading: %1").arg(updateData.at(transferStep).itemName));
}
void MainWindow::slotFileDownloaded(QNetworkReply* reply)
{
if (reply && (reply->error() != QNetworkReply::NoError))
{
ui->statusBar->clearMessage();
if (!isSingleFile)
{
const QString strTemp = tr("An error occurred while downloading \"%1\": %2 (error message: %3)")
.arg(updateData.at(transferStep).downloadName).arg(reply->error()).arg(reply->errorString());
QMessageBox::critical(this,tr("Error in download"),strTemp);
}
else
{
//irrelevant...
}
finished(false);
return;
}
qDebug() << "To write: " << reply->bytesAvailable();
QByteArray downloadedData = reply->readAll();
reply->deleteLater();
poReply->deleteLater();
//![]
static const QString tempFilePath = QDir::tempPath();
if (!isSingleFile)
{
QFile file(tempFilePath + "/" + updateData.at(transferStep).downloadName);
if (!file.open(QFile::WriteOnly | QFile::Truncate))
{
qDebug() << "Failure opening temp file to write: " << file.fileName();
QMessageBox::critical(this,
tr("Error"),
tr("An error occured while trying to open a temporary file to write the downloaded data (file: %1).").arg(file.fileName()));
transferStep = downloadStepCount;
slotFileUploaded(NULL);
return;
}
qint32 bytesWritten = file.write(downloadedData);
file.flush();
if (downloadedData.size() != bytesWritten)
qDebug() << "Write failed, wrote" << bytesWritten << "out of" << downloadedData.size() << "bytes.";
else
qDebug() << "Wrote " << bytesWritten << "bytes.";
file.close();
//![]
if (++transferStep >= downloadStepCount)
{
qDebug() << "Start hash check";
slotStartHashCheck();
return;
}
processNextDownload();
}
else
{
//irrelevant...
}
}
И вот почему я получаю (последнее числовое значение после «=» в хеш-коде — это размер файла):
Итак, что мне не хватает?
qint32 bytesWritten = file.write(downloadedData)
может писать меньше, чем предполагалось, но когда вы сравните размеры, вы должны увидеть, не удастся ли это... Размеры на диске совпадают с размерами в Calculated..., я думаю ? Тогда код, вычисляющий хэши, также может иметь ошибки, но они должны отображаться независимо от локального или http-сервера... Я полагаю, загрузка файлов работает другими способами? Браузер, wget и т. д. Было бы также интересно узнать, является ли загруженный файл частичной загрузкой (соответствующей ожидаемому файлу, но усеченной) или он иным образом поврежден. - person Frank Osterfeld   schedule 05.06.2015