[Qt-interest] What does the return value of QIODevice::write mean?
Stephen Kelly
steveire at gmail.com
Sat Dec 4 19:16:13 CET 2010
Hi,
Consider this:
class MyClass
{
/**
Writes data to @p device. Returns false on error and true otherwise.
*/
bool generateData(QOIDevice *device)
{
// 100 bytes of dummy data.
QByteArray data;
data.reserve(100);
data.fill('\0', 100);
const qint64 written = writeData(device, data);
return written == data.size();
}
qint64 writeData(QIODevice *device, const QByteArray &data)
{
const qint64 bytesWritten = device->write(data);
if (bytesWritten < 0)
return -1; // error condition
if (bytesWritten == data.size())
return bytesWritten; // Success condition.
// Between 0 and data.size() bytes were written.
// It what cases can this happen?
// What should I do about it?
}
};
So the question is what should I do if QIODevice tells me it couldn't write
all the data, but there was no error. Also what else is QIODevice telling me
in that case? Is it saying 'I have processed that many bytes of your data,
so you can forget about them. I didn't do anything about the remaining
bytes.'?
Should I do something like
qint64 bytesSoFar = 0;
while(bytesSoFar != data.size()) {
const qint64 remaining = data.size() - bytesSoFar;
bytesSoFar += device.write(data.constData() + bytesSoFar, remaining);
}
?
That doesn't give any chance to re-enter the event loop, so I'm guessing it
won't work for a general QIODevice.
So do I need to do my own buffering whenever writing to a QIODevice and use
the bytesWritten signal?
class MyClass : public QObject
{
public:
/**
Writes data to @p device. Returns false on error and true otherwise.
*/
qint64 writeData(QOIDevice *device, const QByteArray &data)
{
// ... as above
// Between 0 and data.size() bytes were written.
// Write the rest to a buffer and try to write it later.
m_device = QWeakPointer(device);
const int remaining = data.size() - bytesWritten;
m_buffer += QByteArray(data.constData() + bytesWritten, remaining);
connect(device, SIGNAL(bytesWritten(qint64)),
SLOT(onBytesWritten(qint64)));
// We tell callers that all data is processed because what was
// not written is now buffered.
return data.size();
}
signals:
void error();
private slots:
void onBytesWritten(qint64 numBytes)
{
if (!m_device) {
emit error();
return;
}
m_buffer = m_buffer.right(m_buffer.size() - numBytes);
const qint64 bytesWritten = writeData(m_device, m_buffer);
if (bytesWritten == m_buffer.size())
disconnect(device, SIGNAL(bytesWritten(qint64)),
SLOT(onBytesWritten(qint64)));
}
private:
QWeakPointer<QIODevice> m_device;
QByteArray m_buffer;
};
Is this what all attempts to write to a QIODevice must look like? Or am I
missing something?
Even if writing to a QIODevice which buffers internally like QFile, there is
a limit to the size of that internal buffer, so even a buffered device might
return !data.size().
All the best,
Steve.
More information about the Qt-interest-old
mailing list