Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QIODevice write and read operate inconsistently



  • Hi.

    I'd like to ask your opinion about the read and write behavior of QIODevice classes, which seems to be inconsistent and unexpected (to me at least). Here's what I mean:

        QImage sourceImg(8, 4, QImage::Format_Grayscale8);
        QImage destImg;   
        sourceImg.fill(Qt::gray);
       
        buffer.open(QIODevice::WriteOnly);
        dataStream << sourceImg;
        buffer.close();
    
        buffer.open(QIODevice::ReadOnly);
        dataStream >> destImg;
    
        qDebug() << sourceImg;
        qDebug() << destImg;
    

    The above snippet works as expected, as the output for sourceImg and destImg will be the same:

    QImage(QSize(8, 4),format=QImage::Format_Grayscale8,depth=8,devicePixelRatio=1,bytesPerLine=8,sizeInBytes=32)
    QImage(QSize(8, 4),format=QImage::Format_Grayscale8,depth=8,devicePixelRatio=1,bytesPerLine=8,sizeInBytes=32)
    

    On the other hand, even though the following code looks pretty similar,...

        QImage sourceImg(8, 4, QImage::Format_Grayscale8);
        QImage destImg;   
        sourceImg.fill(Qt::gray);
       
        buffer.open(QIODevice::ReadWrite);
        dataStream << sourceImg;
        dataStream >> destImg;
    
        qDebug() << sourceImg;
        qDebug() << destImg;
    

    ...unfortunately it doesn't produce the same result:

    QImage(QSize(8, 4),format=QImage::Format_Grayscale8,depth=8,devicePixelRatio=1,bytesPerLine=8,sizeInBytes=32)
    QImage(null)
    

    Could somebody explain what is the difference? According to the documentation QIODevice::ReadWrite is exactly the same as QIODevice::ReadOnly | QIODevice::WriteOnly. Do I need to close the device for the data to be actually written? Could this be a bug?

    Info:
    GCC 9.2.0
    Qt 5.13.2
    Linux 4.19.86

    Thanks for reading.


  • Moderators

    After you've written the sourceImg your position in the steam is at the end of the buffer. There's no data after that so there's nothing to read and you get a null image.

    If you want to read it back you need to seek back to the start of the image data in the buffer i.e. use buffer.pos() to get the position before you write to the stream and then buffer.seek(position) to go back before you read.

    This is of course assuming your QIODevice is random-access.


  • Qt Champions 2019

    @PusRob said in QIODevice write and read operate inconsistently:

    Could somebody explain what is the difference?

    QDataStream only has one read/write pointer, not two. So 'dataStream >> destImg;' can't read anything.



  • @Christian-Ehrlicher

    OK, that explains a lot. I thought read and write operations were treated differently somehow, but it seems I was wrong. Thanks.

    Just one more thing out of curiosity: If I'm storing a list of temp files, and I need to read from them now and then, then which is the better thing to do:

    1. create temp file, then close it immediately. If I need to read from it (which is not guaranteed to happen), open file, read data and close it again.
    2. create temp file, keep it open always, and read from it if and when I need to.

    Is option #1 significantly more expensive? Does option #2 need more memory during runtime?

    Thanks.


  • Qt Champions 2019

    @PusRob said in QIODevice write and read operate inconsistently:

    Does option #2 need more memory during runtime?

    I don't think a QFile object consumes that much memory :)



  • @Christian-Ehrlicher
    Thanks for the reply, but I wasn't really concerned about the QFile object itself (you have to use it anyway), but instead if there is a difference in memory consumption between and opened or closed file (maybe because an opened file buffers some of the (meta) data?) Anyway, I'll look into it myself.


Log in to reply