[Interest] reading from and writing to a file with QDataStream

Murphy, Sean smurphy at walbro.com
Mon Mar 7 16:27:07 CET 2016


Your issue boils down to the fact that QByteArray != QString combined with how QDataStream serializes data. According to the documentation for serializing data through a QDataStream (http://doc.qt.io/qt-5/datastreamformat.html) and your code, you have these two things involved:
QString If the string is null: 0xFFFFFFFF (quint32) Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
QByteArray If the byte array is null: 0xFFFFFFFF (quint32) Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes

>  QDataStream out(&bai, QIODevice::WriteOnly);
>  out << QString("A QString"); // writes some information on it
So at this point, the QByteArray "bai" contains 4 bytes for the size of the QString in UTF-16 format (this value is 18, 9 characters at 2 bytes per character), followed by the string itself in UTF-16 format.

>  QByteArray bai;
>  out2 << bai.size();
>  out2 << bai;
Here you wrote out an int and a QByteArray, so the file contains 4 bytes for the int "bai.size()" (value of 22), and then because of how QDataStream serializes QByteArrays, another 4 bytes for the size of the QByteArray (still a value of 22), plus the contents of the QByteArray itself. At this point, remember that the contents of the QByteArray are 4 bytes for the size of the QString (value of 18) plus the QString in UTF-16 format. 

>  QString str;
>  int a;                  // extracts size information
>  in >> a >> str;         // extracts QString
But here you're reading in an int and a QString. So you've read in the int for the size that you explicitly wrote out (the first value of 22), but because you're now reading in a QString, not a QByteArray, you're grabbing the 4 bytes that were supposed to be the size of a QByteArray and treating that as the size of a QString, so the string extraction operation reads in a 22, and then uses the next 22 bytes to build up a QString.

So you need to ensure you are reading and writing the same things. You put an int and a QByteArray in, so you should read an int and a QByteArray out. Then since you know what the contents of the QByteArray are, you can extract that back to a QString...

Sean


More information about the Interest mailing list