我正在尝试将“大”文件(~100MB)发送到我的 RestAPI,但我遇到了 QHttpMultiPart 的问题。
我用来将本地文件从客户端发送到服务器的代码非常简单:
// Create multi-part
QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
// Open file
QFile* file = new QFile(myFilePath);
file->setParent(multiPart);
// -- snip: Check if opening the file was success full --
// Create file part
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader,
QVariant("multipart/form-data"));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"file\"; filename=\"" +
file->fileName() + "\""));
filePart.setBodyDevice(file); // <--- Set the file as body device
// Add file part
multiPart->append(filePart);
// Setup request
QNetworkRequest testRequest { myApiUrl };
testRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"multipart/form-data");
testRequest.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"file\"; filename=\"" +
myFileName + "\""));
// -- snip: Some SSL configuration --
// Send request
auto reply = m_networkAccessManager.post(testRequest, multiPart);
m_testReply.reset(reply);
上面的代码对于非常小的文件(包含一些单词作为内容的 .txt 文件)工作得很好,但如果文件变大(例如 202KB 的 pdf 文件)就会失败。当尝试发送更大的文件时,我的 GUI 变得没有响应,我需要关闭应用程序(我的 RAM 或 CPU 使用率在被冻结时不会显着增加)。
我看过这个 stackoverflow 对话:使用 POST 上传大文件会冻结系统(参见解决方案),据我所知,我没有做任何真正不同的事情,但我的应用程序仍然冻结。
我在提供给我的 QNetworkReply 的信号中添加了一些插槽,以获取有关进度的通知:
connect(m_testReply.get(), &QNetworkReply::uploadProgress,
[](qint64 bytesSent, qint64 bytesTotal)
{
qDebug() << QString::number(bytesSent) + " of " +
QString::number(bytesTotal) + " uploaded";
});
connect(m_testReply.get(), &QNetworkReply::finished,
[]()
{
qDebug() << "Upload finished!";
});
使用这些连接运行我的应用程序只会给我这个输出:
"16381" of "201324" uploaded
。
根据我的理解,它只成功发送了一个块并在冻结后,这解释了为什么小文件被成功发送,因为它们只包含一个块。
我的 RestAPI 期待内容类型为“multipart/...”的 HTTP 请求,它可以很好地接收和处理小文件。对于具有多个块的文件,它读取第一个但在卡住(无限)等待下一个块之后。
提前感谢您的帮助。