[Interest] QFile::write(const QByteArray&) does not write, all data?

Thiago Macieira thiago.macieira at intel.com
Mon May 14 17:45:06 CEST 2018


On Monday, 14 May 2018 00:32:38 PDT alexander golks wrote:
> > int QDataStream::writeRawData(const char *s, int len)
> > {
> > 
> >     CHECK_STREAM_WRITE_PRECOND(-1)
> >     int ret = dev->write(s, len);
> >     if (ret != len)
> >         q_status = WriteFailed;
> >     return ret;
> > 
> > }
> 
> it does, partly. the write has not failed, it simply has not written all
> data.

It's a matter of perspective. As seen in this thread, in some situations 
failing to write everything is an unrecoverable situation. That is the case 
here: QDataStream cannot recover from a partial write.

We could loop retrying the write so long as ret > 0. This is probably 
acceptable here, since the alternative is to go into WriteFailed state anyway.

Would you submit an update?

> > > otherwise, as i still don't know the "no-error" conditions, i would
> > > always
> > > need to use something like QDataStream::writeRawData, which is barely
> > > more
> > > then a QFile::write, and no other operator<< methods.
> > 
> > it will tell you if there was a write failure. See above.
> 
> yes, but all other operator<< methods not.

The other methods do the same:

QDataStream &QDataStream::operator<<(qint16 i)
{
    CHECK_STREAM_WRITE_PRECOND(*this)
    if (!noswap) {
        i = qbswap(i);
    }
    if (dev->write((char *)&i, sizeof(qint16)) != sizeof(qint16))
        q_status = WriteFailed;
    return *this;
}

Inserting the loop requires a bit of refactoring to centralise the writing to 
the device.

> what about something like:
> 
> int QDataStream::writeRawData(const char *s, int len)
> {
>     CHECK_STREAM_WRITE_PRECOND(-1)
>     qint64 bytesToWrite = len;
>     qint64 totalWritten = 0;
>     do {
>         int ret = dev->write(s + totalWritten, bytesToWrite);
>         if(ret < 0)
> 	    break;
>         totalWritten += ret;
>         bytesToWrite -= ret;
>     } while (totalWritten < len);
>     if(totalWritten != len)
>         q_status = WriteFailed;
>     return totalWritten;
> }
> 
> and appropriate modifications for all other related methods.

Please submit via the code review system.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center






More information about the Interest mailing list