Search code examples
c++qtread-writeqtextstreamqbuffer

Repeatedly write and read to/from QBuffer via QTextStream


I am trying to repeatedly write and read to/from a QBuffer object via QTextStream. First I construct both objects:

QBuffer b;
b.open(QIODevice::ReadWrite);
QTextStream s(&b);
// Setup text stream here

Then I write three different portions of information and read them back:

s << "Test" << 666 << endl << flush;
s.seek(0);
qDebug() << s.readAll();

s << "X" << endl << flush;
s.seek(0);
qDebug() << s.readAll();

s << "Test" << 777 << endl << flush;
s.seek(0);
qDebug() << s.readAll();

Of course I do not get the data portion I wrote immediately before, but the cumulated data:

"Test666\n"
"Test666\nX\n"
"Test666\nX\nTest777\n"

I could do adaptive seek calls to get the correct data but I do not want the QBuffer to grow infinitely.

I tried a s.reset() call between writes but the result is the same. Calling reset() or open()/close() directly on the buffer gives a crippled result (which is expected since the stream is bypassed):

"Test666\n"
"X\nst666\n"
"Test777\n"

I could probably build a new buffer for every cycle, open it and attach it to the stream but that is slow.

Is there a proper and fast solution for this use case?


Solution

  • You can access QBuffer's internal QByteArray storage directly with QBuffer::buffer() and then delete everything with QByteArray::clear(). Then manually seek() back to the start.

        QBuffer b;
        b.open(QIODevice::ReadWrite);
        QTextStream s(&b);
    
        s << "Test" << 666 << endl << flush;
        s.seek(0);
        qDebug() << s.readAll();
    
        b.buffer().clear();
        s.seek(0);
    
        s << "X" << endl << flush;
        s.seek(0);
        qDebug() << s.readAll();
    
        b.buffer().clear();
        s.seek(0);
    
        s << "Test" << 777 << endl << flush;
        s.seek(0);
        qDebug() << s.readAll();
    
    "Test666\n"
    "X\n"
    "Test777\n"
    

    QTextStream also has a constructor which takes a QByteArray directly and creates the QBuffer automatically, which may save a little code in this case.