使用POST上传大文件会冻结系统

时间:2015-06-08 16:01:09

标签: macos qt file-upload qnetworkaccessmanager

我有一个使用标准发布请求将文件(视频文件)上传到服务器的应用程序,如:

QNetworkRequest  request(QUrl("myUrl"));
QString bound="margin";
QByteArray data(QString("--"+bound+"\r\n").toLatin1());

data += "Content-Disposition: form-data; name=\"media_id\"\r\n\r\n";
data += id + "\r\n";
data += QString("--" + bound + "\r\n").toLatin1();

QString str = "Content-Disposition: form-data; name=\"file\"; filename=\"" + name + "\r\n";
data += str;
data += "Content-Type: video/mp4\r\n\r\n";

QFile f(path);
if(! f.open(QIODevice::ReadOnly))
{
    qDebug() << "uploadMediaRequest error opening " << path;
    return false;
}


QByteArray bytes;
bytes = f.readAll();

data.append(bytes);
data += "\r\n";
data += QString("--" + bound + "\r\n.").toLatin1();
data += "\r\n";

f.close();

request.setRawHeader(QString("Accept").toLatin1(),QString("application/json, text/javascript, */*; q=0.01").toLatin1());
request.setRawHeader(QString("Origin").toLatin1(),QString("http://dev.teamhood.io").toLatin1());
request.setRawHeader(QString("API-Client").toLatin1(),QString("desktop").toLatin1());
request.setRawHeader(QString("withCredentials").toLatin1(), QString("true").toLatin1());
request.setRawHeader(QString("Content-Type").toLatin1(),QString("multipart/form-data; boundary=" + bound).toLatin1());
request.setRawHeader(QString("Content-Length").toLatin1(), QString::number(data.length()).toLatin1());

然后POST该请求。 对于1GB或更少的文件,它工作得很好,但如果我尝试上传1,5GB的文件,我得到

myProgramName[948:32028] Communications error: <OS_xpc_error: <error: 0x7fff7c37bb60> { count = 1, contents =
"XPCErrorDescription" => <string: 0x7fff7c37bfa8> { length = 22, contents = "Connection interrupted" }}>
Got xpc error message: Connection interrupted

和应用程序和SO冻死。 我想我可以分割大文件并将它们分成几部分上传并让服务器组装它们但我想知道你是否有人能给我一些解释这些奇怪的错误。

我使用OSX&amp; Qt 5.4,提前thx!

1 个答案:

答案 0 :(得分:1)

由用户Pavel Strakhov解决:

QNetworkRequest request(QUrl("myUrl"));

QFile *f = new QFile(path);
if(! f->open(QIODevice::ReadOnly))
{
    qDebug() << "uploadMediaRequest error opening " << path;
    return false;
}

QHttpMultiPart * multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart idPart, mediaPart;
idPart.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"media_id\""));
idPart.setBody(id.toLatin1());

mediaPart.setHeader(QNetworkRequest::ContentTypeHeader, type); 
mediaPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\""+ name + "\""));
mediaPart.setBodyDevice(f);
f->setParent(multiPart); 

multiPart->append(idPart);
multiPart->append(mediaPart);

request.setRawHeader(QString("Accept").toLatin1(),QString("application/json, text/javascript, */*; q=0.01").toLatin1());
request.setRawHeader(QString("Origin").toLatin1(),QString("http://dev.teamhood.io").toLatin1());
request.setRawHeader(QString("API-Client").toLatin1(),QString("desktop").toLatin1());
request.setRawHeader(QString("withCredentials").toLatin1(), QString("true").toLatin1());

networkManager->post(request, multiPart));

现在运行得很好。