QNetworkAccessManager 读取传出数据并将其保存在 QIODevice
Posted
技术标签:
【中文标题】QNetworkAccessManager 读取传出数据并将其保存在 QIODevice【英文标题】:QNetworkAccessManager read outgoingData and keep it in QIODevice 【发布时间】:2011-03-27 16:29:59 【问题描述】:我正在尝试将所有传出的 POST 数据保存在 QtWebKit 中。
我使用重写 QNetworkReply *QNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice outgoingData) 方法并读取包含传出 POST 数据的传出数据。
问题是读取后,数据在QIODevice中变得不可用。
如何保存传出(PUT、POST)数据并使其可用于未来的内部 Qt 操作?
如果我需要使用其他方法来保存 PUT/POST 数据 - 请告诉我。
代码示例:
QNetworkReply *MyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
QByteArray bArray = outgoingData->readAll();
// save bArray (that contains POST outgoing data) somewhere
// do other things, and outgoingData now has no data anymore, as it was already read to bArray
我试过了
QByteArray bArray = outgoingData->readAll();
outgoingData->write(bArray);
qDebug() << bArray;
但在这种情况下,我收到“QIODevice::write: ReadOnly device”消息。
如何在 Qt 中保存传出的 POST/PUT 数据?
谢谢。
【问题讨论】:
您能否在您的问题中添加有关您需要这些数据用于什么目的的信息?给我们更广阔的视野。 【参考方案1】:qint64 QIODevice::peek (char * data, qint64 maxSize)
最多从 设备转化为数据,无副作用 (即,如果您在之后调用 read() peek(),你会得到相同的数据)。 返回读取的字节数。如果 发生错误,例如当 试图窥视打开的设备 WriteOnly 模式,此函数返回 -1.
当没有更多数据时返回0 可供阅读。
编辑
忘记 peak(),在这种情况下不好。您可以使用它,但您必须做很多工作才能完成您的要求。而是阅读Tee is for Tubes,从那里获取代码并使用它。
链接由 peppe 提供,来自http://irc.freenode.net 的#qt irc 频道。 我要感谢 peppe 和 thiago,他们非常好心地在#qt 频道上与我讨论这个问题。
如果有一天您想窃取来自 QNetworkAccessManager 的传入(而不是传出)数据,您可以在 How to read data from QNetworkReply being used by QWebPage? 问题中找到答案和代码。
【讨论】:
看起来是一个正确的解决方案,我做的输出数据->peek(100000);我尝试使用输出数据->size() 获取 maxSize,但它始终返回 0。如何获取数据的确切 maxSize?还是随机的大数就可以了? @izyda 我不确定我写这篇文章时的意思,但现在考虑这个问题似乎是 a) 何时到peek
,因为 QtWebKit 可以随时读取数据(参考作为问题中的内部Qt操作)和b)如何跟踪偷看的内容,或者换句话说,如何在偷看的数据和从QIODevice
中读取并仍然存在的数据之间保持同步.基本上要做到这一点,您必须创建与我的答案编辑中提到的Grantlee::Tee
非常相似的东西。
对 - 所以考虑到我最感兴趣的是读取传入的数据,我最好继承 QNetworkReply 并在 QWebPage 获取数据之前从那里读取数据......【参考方案2】:
在这种特殊情况下,使用 pos() 和 seek() 实际上不起作用。使用 peek() 的想法似乎要好得多。但是一个例子会很有帮助。所以,这里有一个示例,说明如何在函数 createRequest() 中从给定 QIODevice 的传出数据中获取数据缓冲区,而不影响原始数据。
if (outgoing != NULL)
const qint64 delta = 100;
qint64 length = delta;
QByteArray array;
while (true)
char *buffer = new char[length];
qint64 count = outgoing->peek(buffer, length);
if (count < length)
array = QByteArray(buffer, count);
delete buffer;
break;
length += delta;
delete buffer;
为了优化,您可以调整 'delta' 的值。
【讨论】:
效率较低,因为第一段可能会被多次读取。【参考方案3】:使用 QIODevice::pos()
保存 IO 设备标记。从中读取数据。然后用QIODevice::seek()
恢复标记。
这只有在设备是随机访问设备时才有效。但我认为它涵盖了大部分。
【讨论】:
IO 设备是顺序的。 pos() 总是返回 0以上是关于QNetworkAccessManager 读取传出数据并将其保存在 QIODevice的主要内容,如果未能解决你的问题,请参考以下文章
QNetworkAccessManager:从串行 QIODevice 发布 http 多部分
QNetworkAccessManager 用 url 打开一个 json 数据
错误:没有用于调用“QNetworkAccessManager::QNetworkAccessManager(Networking* const)”的匹配函数