问题
I have a class ContactData and a class FriendList holding a QList and I overloaded the << / >> operators.
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;
saving function
QString path = "/friendlist.bin";
QFile file(path);
if (file.open(QIODevice::WriteOnly))
{
QDataStream out(&file);
out << m_friendList;
file.close();
}
loading function
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();
}
}
It does save a file in the desired direction, but unfortunately loading gives me an empty list of the size 0. This is where I'm stuck..
Can anyone help?
回答1:
From your code to rebuild list:
for(int i = 0; i < list->size(); i++)
Problem is that when you're deserializing into an empty list size()
will return 0 (or a value completely unrelated to what you have to read from disk) and anyway you have to read items from stream, it doesn't matter actual list size. Moreoverlist is empty so you have first to create a new element (you can't just call at()
because there aren't elements inside). You can write an integer (for example) before items then read it when deserializing:
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;
}
Do not forget to write count
in serialization function too. As alternative you may read everything until end of input stream:
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;
}
To finish check what Kamil said in comment, if you don't have any error during serialization probably it's just a typo but...
回答2:
You do not need to overload the >>
and <<
operators for QList
, they already exist when the left-hand operator is QDataStream
see the documentation
As long as an individual object can serialise and deserialise correctly, all Qt containers should also serialise and deserialise.
回答3:
Thanks to everyone who submitted help, now it works fine to me. For those who are interested, here is what I had to change:
saving function
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;
}
来源:https://stackoverflow.com/questions/21186434/save-and-load-qlistclass-to-file