2015-06-08 26 views
0

我有上傳文件(視頻文件)到服務器使用標準要求後,像其中的應用程序:上傳大文件用POST凍結系統

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()); 

然後張貼的請求。 對於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 & Qt 5.4,thx提前!

+2

將1.5 GB數據讀入單個陣列並不是最好的主意。你應該使用'QNetworkAccessManager :: post(const QNetworkRequest&request,QHttpMultiPart * multiPart)',因爲'QHttpMultiPart'允許通過'QHttpPart :: setBodyDevice'添加上傳文件。在這種情況下,文件將由Qt以小塊的形式在內部讀取。 –

+0

Ty爲您提供幫助。我改變了後調用,包括'QHttpMultiPart * multiPart = new QHttpMultiPart(QHttpMultiPart :: FormDataType); multiPart-> setBoundary(data);'雖然更好的做法,錯誤仍然存​​在 – Cits

+1

我不明白你做了什麼。首先,'setBoundary'用於更改用於分隔多部分數據的邊界字符串。你根本不應該改變它,更別說把你的數據放在裏面了。其次,如果你仍然有'數據'變量,你仍然在內存中讀取你的所有文件,這是不可接受的。嘗試完全刪除文件讀取,並使用'QHttpMultiPart'和'QHttpPart'功能將文件內容放入請求中。 –

回答

1

用戶帕維爾·斯特拉霍夫解決:

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)); 

現在它運行很好。