可执行文件在被复制时被损坏 [英] Executable getting somehow corrupted when being copied
问题描述
我使用Qt的QNetworkAccessManager从一个地方(当前本地机器,但在将来它将是一个HTTP服务器)下载文件,并临时存储在TEMP文件(linux ubuntu)。我发现的问题是,该文件(这是一个可执行文件)在进程中被损坏:当我尝试将该文件作为可执行文件运行时,它返回有问题的交叉编译的经典错误。
I'm using Qt's QNetworkAccessManager to download a file from a place (currently the local machine, but in the future it will be an HTTP server) and temporarily store it in the TEMP file (linux ubuntu). The problem I've found is that the file (which is an executable) gets corrupted in the process: when I try to run the file as executable, it returns a classical error of problematic cross-compilation.
这很有趣,因为该文件是嵌入式Linux设备的可执行文件 - 我将可执行文件下载到我的TEMP,以便稍后将其发送到设备。当出现这种情况时(使用FileZilla),会出现以下错误信息:
Now that's interesting because the file is a executable for a Embedded Linux Device - I'm downloading the executable to my TEMP so I may send it later to the device. When that happens (using FileZilla), though, this error message appears:
./ re8k_interface-tgt:line 1:syntax error:unexpected word(expecting))
./re8k_interface-tgt: line 1: syntax error: unexpected word (expecting ")")
现在我知道原始文件可以通过将其复制到设备并运行,知道它与复制文件的过程有关,无论是在下载或写入QFile对象时。这是我现在做的:
Now I know the original file is fine by copying it to the device and running it, so I'm aware it has something to do with the process of copying the file, either when downloading or when writing to a QFile object. Here is how I'm doing it for now:
//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:我知道设置权限的必要性
P.s.: I'm aware of the necessity of setting permissions
复制的文件大小与原始大小完全匹配。那么,我不能看到的问题在哪里?
The copied file size matches exactly the original. So, where is the problem I can't see?
推荐答案
将字节数组写入 QDataStream
只要不使用数据流,使用 QFile
,或者更好<$
Simply don't use the data stream, use QFile
, or, better QTemporaryFile
directly.
下面的例子演示了如何利用C ++ 11和Qt 5使它非常简单: / p>
The example below demonstrates how to leverage C++11 and Qt 5 to make it really simple:
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();
}
这篇关于可执行文件在被复制时被损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!