Tôi đang cố gắng sử dụng QNetworkAccessManager để tải lên các đa số http lên một máy chủ chuyên dụng.QNetworkAccessManager: đăng http multipart từ số seri QIODevice
Multipart bao gồm phần JSON mô tả dữ liệu đang được tải lên.
Dữ liệu được đọc từ một QIODevice nối tiếp, mã hóa dữ liệu.
Đây là mã tạo yêu cầu nhiều phần dữ liệu:
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart metaPart;
metaPart.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
metaPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"metadata\""));
metaPart.setBody(meta.toJson());
multiPart->append(metaPart);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(fileFormat));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\""));
filePart.setBodyDevice(p_encDevice);
p_encDevice->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(filePart);
QNetworkAccessManager netMgr;
QScopedPointer<QNetworkReply> reply(netMgr.post(request, multiPart));
multiPart->setParent(reply.data()); // delete the multiPart with the reply
Nếu p_encDevice là một thể hiện của QFile, tập tin đó được tải lên tốt.
Nếu mã hóa chuyên biệt QIODevice được sử dụng (thiết bị nối tiếp) thì tất cả dữ liệu được đọc từ thiết bị tùy chỉnh của tôi. tuy nhiên QNetworkAccessManager :: post() không hoàn thành (bị treo).
Tôi đọc trong tài liệu của QHttpPart rằng:
nếu thiết bị là tuần tự (ví dụ như ổ cắm, nhưng không phải tập tin), QNetworkAccessManager :: bài() nên được gọi sau khi thiết bị đã phát ra thành() .
Rất tiếc, tôi không biết cách thực hiện điều đó.
Vui lòng thông báo.
EDIT:
QIODevice không có() khe thành ở tất cả. Hơn nữa, đọc từ IODevice tùy chỉnh của tôi không xảy ra chút nào nếu QNetworkAccessManager :: post() không được gọi và do đó thiết bị sẽ không thể phát ra một sự kiện như vậy. (Catch 22?)
EDIT 2:
Dường như QNAM không làm việc với các thiết bị liên tục ở tất cả. Xem discussion on qt-project.
EDIT 3:
tôi quản lý để "đánh lừa" QNAM để làm cho nó nghĩ rằng nó được đọc từ các thiết bị không tuần tự, nhưng tìm kiếm và thiết lập lại chức năng ngăn chặn tìm kiếm. Điều này sẽ hoạt động cho đến khi QNAM thực sự sẽ cố gắng tìm kiếm.
bool AesDevice::isSequential() const
{
return false;
}
bool AesDevice::reset()
{
if (this->pos() != 0) {
return false;
}
return QIODevice::reset();
}
bool AesDevice::seek(qint64 pos)
{
if (this->pos() != pos) {
return false;
}
return QIODevice::seek(pos);
}
Tôi nghĩ rằng tín hiệu thích hợp là 'QIODevice :: readChannelFinished()'. Về cơ bản 'QIODevice :: bytesAvailable()' phải trả về giá trị đúng cho nó hoạt động. –
Bạn đã giải quyết vấn đề kể từ đó, matejk? – lpapp
Tôi đã xoay sở để giải quyết nó, nhưng không phải là một cách rõ ràng. Xem bình luận của tôi dưới đây. – matejk