保存并将QList <class *>加载到文件</class *>

时间:2014-01-17 12:48:40

标签: c++ qt qlist qdatastream

我有一个ContactData类和一个持有QList的FriendList类,我重载了&lt;&lt; /&gt;&gt;运算符。


contactdata.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);

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;
}

friendlist.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);

friendlist.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的空列表。 这就是我被困住的地方..

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

您不需要为>>的{​​{1}}和<<运算符重载,当左侧运算符为QList时,它们已经存在

请参阅the documentation

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

答案 1 :(得分:0)

从您的代码到重建列表:

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;
}

要完成检查评论中Kamil said的内容,如果序列化过程中没有任何错误,可能只是一个错字但是......

答案 2 :(得分:0)

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

保存功能

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

friendlist.cpp

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