Исполняемый файл как-то поврежден при копировании

Я использую Qt QNetworkAccessManager, чтобы загрузить файл с места (в настоящее время это локальный компьютер, но в будущем это будет HTTP-сервер) и временно сохранить его в файле TEMP (linux ubuntu). Проблема, которую я обнаружил, состоит в том, что файл (который является исполняемым файлом) повреждается в процессе: когда я пытаюсь запустить файл как исполняемый, он возвращает классическую ошибку проблемной кросс-компиляции.

Это интересно, потому что файл является исполняемым файлом для встраиваемого устройства Linux — я загружаю исполняемый файл в свой TEMP, чтобы позже отправить его на устройство. Когда это происходит (используя FileZilla), появляется следующее сообщение об ошибке:

./ re8k_interface-tgt: строка 1: синтаксическая ошибка: неожиданное слово (ожидание «)»)

Теперь я знаю, что с оригинальным файлом все в порядке, скопировав его на устройство и запустив его, поэтому я знаю, что он как-то связан с процессом копирования файла, либо при загрузке, либо при записи в объект QFile. Вот как я делаю это сейчас:

//Call to download
QUrl ulrTemp("//" + downloadUrls[downloadStep].arg(ui->sbID->text()));
ulrTemp.setScheme("file");

qDebug() << "Downloading from" << ulrTemp;

poReply = downloadNetworkManager->get(QNetworkRequest(ulrTemp));

connect(poReply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(slotTransferProgress(qint64,qint64)));
connect(poReply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotTransferError(QNetworkReply::NetworkError)));//When finished
QByteArray downloadedData;
downloadedData = reply->readAll();

reply->deleteLater();
poReply->deleteLater();

static const QString tempFilePath = QDir::tempPath();

QFile file(tempFilePath + "/" + downloadNames[downloadStep]);

if (!file.open(QFile::WriteOnly | QFile::Truncate))
{
qDebug() << "Failure opening temp file to write: " << file.fileName();

return;
}

QDataStream stream(&file);

stream << downloadedData;

file.close();

PS: я знаю о необходимости установки разрешений

Размер скопированного файла точно соответствует оригиналу. Так в чем же проблема, которую я не вижу?

2

Решение

При записи байтового массива в QDataStreamдлина массива также записывается.

Просто не используйте поток данных, используйте QFile, или лучше QTemporaryFile непосредственно.

Пример ниже демонстрирует, как использовать C ++ 11 и Qt 5, чтобы сделать его действительно простым:

Writing to: /var/folders/yy/2tl/T/download-29543601.L91178
Wrote  55015 bytes.
Downloaded 55015 of -1 bytes
Wrote  7572 bytes.
Wrote  6686 bytes.
Wrote  5104 bytes.
Downloaded 74377 of 74377 bytes
Successfully wrote /var/folders/yy/2tl/T/download-29543601.L91178
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTemporaryFile>
#include <QUrl>
#include <QByteArray>
#include <QTextStream>
#include <QDebug>
#include <cstdio>

QTextStream out(stdout);
QTextStream in(stdin);

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QNetworkAccessManager mgr;

auto url = QUrl("http://stackoverflow.com/questions/29543601/""executable-getting-somehow-corrupted-when-being-copied");
auto reply = mgr.get(QNetworkRequest(url));

QTemporaryFile file;
if (!file.open()) {
qDebug() << "Can't open file for writing.";
return -1;
}
out << "Writing to: " << file.fileName() << endl;

QObject::connect(reply, &QNetworkReply::downloadProgress, [](qint64 rx, qint64 total) {
qDebug() << "Downloaded" << rx << "of" << total << "bytes";
});

QObject::connect(reply, &QIODevice::readyRead, [reply, &file]{
auto data = reply->readAll();
auto written = file.write(data);
if (data.size() != written) {
qDebug() << "Write failed, wrote" << written << "out of" << data.size() << "bytes.";
} else {
qDebug() << "Wrote " << written << "bytes.";
}
});

QObject::connect(reply, &QNetworkReply::finished, [reply, &file]{
if (reply->error() != QNetworkReply::NoError) {
qDebug() << "The request was unsuccessful. Error:" << reply->error();
qApp->quit();
return;
}
if (file.flush()) {
out << "Successfully wrote " << file.fileName();
out << "\nPress Enter to remove the file and exit." << flush;
in.readLine();
} else {
qDebug() << "The file flush has failed";
}
qApp->quit();
});

return a.exec();
}
2

Другие решения


По вопросам рекламы [email protected]