我们对QIODevice::write的一般行为和具体的QTcpSocket实现感到非常困惑。已经有了一个similar question,但答案并不令人满意。主要的困惑分别来自于bytesWritten信号的waitForBytesWritten方法。这两个字节似乎表明了从QIODevice使用的缓冲区写入实际底层设备的字节(必须存在这样的缓冲区,否则该方法就没有多大意义)。但问题是,如果QIODevice::write返回的数字与这个数字相对应,或者在这种情况下,它表示存储在内部缓冲区中的字节数,而不是写入底层设备的字节数。如果返回的数字表示写入内部缓冲区的字节,则需要采用如下模式来确保写入所有数据:
void writeAll(QIODevice& device, const QByteArray& data) {
int written = 0;
do {
written = device.write(data.constData() + written, data.size() - written);
} while(written < data.size());
}但是,如果QIODevice::write的返回值与bytesWritten信号的含义相对应,这将插入重复的数据。这方面的文档非常混乱,因为在这两种方法中都使用了“设备”这个词,尽管它看起来合乎逻辑,而且是一般理解,实际上是写到缓冲器上的,而不是设备。
总之,问题是:返回的bye QIODevice::write是写入底层设备的字节数,因此它保存为调用QIODevice::write而不检查返回的字节数,因为所有内容都存储在内部缓冲区中。或者,它是否表示它可以在内部存储多少字节,以及必须使用类似上述writeAll的模式来安全地将所有数据写入设备?
(UPDATE:查看源代码,QTcpSocket::write实现实际上不会返回比一个人想写的字节少的字节,因此不需要上面的writeAll。但是,这是特定于套接字和这个Qt版本的,文档仍然令人困惑.)
发布于 2011-09-22 09:42:12
前面的问题回答了您的问题,QIODevice::write(const char * data, qint64 maxSize)文档也是如此:
最多将从数据写入 maxSize字节到设备。返回实际写入的字节数,如果发生错误,返回-1。
这可能(而且在现实生活中)返回的内容比您所要求的要少,这取决于您是否再次调用write和其余部分。
至于waitForBytesWritten
用于缓冲设备的
,此函数等待到已缓冲的书面数据的有效负载被写入设备.
它只适用于缓冲设备。并不是所有的设备都被缓冲。如果是这样,并且您编写的缓冲区所能容纳的内容不足,write可以在设备完成发送所有数据之前成功返回。
设备不一定是缓冲的。
发布于 2011-09-22 10:08:17
QTcpSocket是一个缓冲的QAbstractSocket。在QAbstractSocket中分配内部缓冲区,并在该缓冲区中复制数据。写的返回值是传递给write()的数据的大小。
waitForBytesWritten一直等到QAbstractSocket的内部缓冲区中的数据写入到本机套接字为止。
https://stackoverflow.com/questions/7512559
复制相似问题