保存并加载 QList<Class*> 到文件

Save and load QList<Class*> to file

本文关键字:gt 文件 Class lt 加载 QList 保存      更新时间:2023-10-16

我有一个类ContactData和一个类FriendList,上面有一个QList,我重载了<</>>运算符。


联系人数据.h

class ContactData
{
//all public for testing
public:
    ContactData();
    QString m_name;
    QString m_description;
    bool m_online; 
};
QDataStream &operator<<(QDataStream& out, ContactData& contactData);
QDataStream &operator>>(QDataStream& in, ContactData* contactData);

联系人数据.cpp

QDataStream &operator<<(QDataStream &out, ContactData& contactData)
{
    out << contactData.m_name;
    out << contactData.m_description;
    return out;
}
QDataStream &operator>>(QDataStream &in, ContactData* contactData)
{
    in >> contactData->m_name;
    in >> contactData->m_description;
    return in;
}

朋友列表.h

#include "contactdata.h"
typedef QList<ContactData*> TFriendList;
class FriendList
{
...
public:
TFriendList* m_list;
...
};
QDataStream &operator<<(QDataStream& out, FriendList& list);
QDataStream &operator>>(QDataStream& in, FriendList* list);

好友列表.cpp

QDataStream &operator<<(QDataStream& out, FriendList& list)
{
    for(int i = 0; i < list.size(); i++)
    {
        ContactData contact = *list.at(i);
        out << contact;
    }
    return out;
}
QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    for(int i = 0; i < list->size(); i++)
    {
        ContactData* contact = list->m_list->at(i);
        in >> contact;
    }
    return in;
}

// typedef QList<ContactData*> TFriendList;
private:
    FriendList* m_friendList;

保存功能

QString path = "/friendlist.bin";
QFile file(path);
if (file.open(QIODevice::WriteOnly))
{
    QDataStream out(&file);
    out << m_friendList;
    file.close();
}

加载功能

QString path = "/friendlist.bin";
QFile file(path);
if(file.exists())
{
  if (file.open(QIODevice::ReadOnly))
  {
     QDataStream in(&file);
     in >> m_friendList;
     file.close();
     qDebug() << "FriendList.size() = " << m_friendList->size();
     }
}

它确实在所需的方向上保存了一个文件,但不幸的是加载给了我一个大小为 0 的空列表。这就是我被困住的地方。

谁能帮忙?

你不需要重载>><<运算符进行QList,当左手运算符QDataStream时,它们已经存在

请参阅文档

只要单个对象可以正确序列化和反序列化,所有Qt容器也应该序列化和反序列化。

从代码到重建列表:

for(int i = 0; i < list->size(); i++) 

问题是,当您反序列化为空列表时size()将返回 0(或与您必须从磁盘读取的内容完全无关的值),无论如何您必须从流中读取项目,实际列表大小无关紧要。此外,list是空的,所以你必须先创建一个新元素(你不能只调用at()因为里面没有元素)。例如,您可以在项目之前写入一个整数,然后在反序列化时读取它:

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    int count = 0;
    in >> count;
    for(int i = 0; i < count; i++)
    {
        ContactData* contact = new ContactData();
        in >> contact;
        list->m_list->push_back(contact);
    }
    return in;
}

不要忘记在序列化函数中编写count。作为替代方案,您可以读取所有内容,直到输入流结束:

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    int count = 0;
    in >> count;
    while (!in.atEnd())
    {
        ContactData* contact = new ContactData();
        in >> contact;
        list->m_list->push_back(contact);
    }
    return in;
}

要完成检查卡米尔在评论中所说的内容,如果您在序列化过程中没有任何错误,可能只是一个错字,但是......

感谢所有提交帮助的人,现在它对我来说很好用。对于那些感兴趣的人,这是我必须更改的内容:

保存功能

if (file.open(QIODevice::WriteOnly))
{
    QDataStream out(&file);
    out << *m_friendList;
    file.close();
}

好友列表.cpp

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    while (!in.atEnd())
    {
        ContactData* contact = new ContactData();
        in >> contact;
        list->m_list->push_back(contact);
    }
    return in;
}