How do you serialize a QMap?

老子叫甜甜 提交于 2019-12-06 09:31:42

The proper QMap serialization and deserialization code is the following:

main.cpp

#include <QString>
#include <QFile>
#include <QMap>
#include <QDataStream>
#include <QDebug>

void write()
{
   QString filename = "snippets.txt";
   QFile myFile(filename);
   if (!myFile.open(QIODevice::WriteOnly))
   {
       qDebug() << "Could not write to file:" << filename << "Error string:" << myFile.errorString();
       return;
   }

   QMap<QString, QString> map;
   map.insert("one", "this is 1");
   map.insert("two", "this is 2");
   map.insert("three", "this is 3");

   QDataStream out(&myFile);
   out.setVersion(QDataStream::Qt_5_3);
   out << map;
}

QMap<QString,QString> read()
{
    QString filename = "snippets.txt";
    QFile myFile(filename);
    QMap<QString, QString> map;
    QDataStream in(&myFile);
    in.setVersion(QDataStream::Qt_5_3);

    if (!myFile.open(QIODevice::ReadOnly))
    {
        qDebug() << "Could not read the file:" << filename << "Error string:" << myFile.errorString();
        return map;
    }

    in >> map;
    return map;
}

int main()
{
    write();
    qDebug() << read();
    return 0;
}

main.pro

TEMPLATE = app
TARGET = main
QT = core
SOURCES += main.cpp

Build and Run

qmake && make && ./main

Output

QMap(("one", "this is 1")("three", "this is 3")("two", "this is 2"))

You have had several issues:

This made it really difficult for you to reveal the real issues.

This was the issue hidden from you without proper error reporting. The problem here is that when you open the file for only writing, any subsequent read operation will yield empty result naturally. It i a bit hidden when doing it through QDataStream, but if you take a quick look at the QIODevice documentation when you read directly through the QFile instance it becomes a bit more clear what is going on underneath for wrong open mode:

Reads at most maxSize bytes from the device into data, and returns the number of bytes read. If an error occurs, such as when attempting to read from a device opened in WriteOnly mode, this function returns -1.

If you checked the errors, this would have become more clear. To be fair, in your case sharing the file without closing it before the operations could have been acceptable in this simple snippet. In that case, you would have used something like re-seek to the beginning and QIODevice::ReadWrite. Having said that, it is just another way of doing it.

  • Incorrect use of qDebug()

This is just a side note, but you were adding spaces explicitly, whereas qDebug() is already doing that for you.

  • Needless flushing of the file when serializing.

This is superfluous as it is automatically done when closing the file descriptor through the class destructor.

  • Needless closure of the file object

This is automatically done by proper RAII. The desctructor will close it for you if the file is still open. Since you leave the scope of the function, the destructor will be called automatically for your file object as it is constructed on the stack.

May be that's because you are opening the file as WriteOnly in your read function. The correct form is:

if (!myFile.open(QIODevice::ReadOnly))
{
    qDebug() << "Could not read " << filename;
    return (map);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!