У меня есть класс ContactData и класс FriendList, содержащий QList, и я перегружен << / >> операторы.
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.
Это где я застрял ..
Кто-нибудь может помочь?
Из вашего кода, чтобы перестроить список:
for(int i = 0; i < list->size(); i++)
Проблема в том, что когда вы десериализуетесь в пустой список size()
вернет 0 (или значение, совершенно не связанное с тем, что вы должны прочитать с диска), и в любом случае вам придется читать элементы из потока, это не имеет значения для фактического размера списка. Кроме того, список пуст, поэтому вы должны сначала создать новый элемент (вы не можете просто вызвать 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;
}
Чтобы закончить, проверьте, что Камил сказал в комментарии, если у вас нет ошибок во время сериализации, возможно, это просто опечатка, но …
Вам не нужно перегружать >>
а также <<
операторы для QList
они уже существуют, когда левый оператор QDataStream
увидеть документация
Пока отдельный объект может сериализоваться и десериализоваться правильно, все контейнеры Qt также должны сериализоваться и десериализоваться.
Спасибо всем, кто предоставил помощь, теперь она отлично работает для меня.
Для тех, кто заинтересован, вот что мне пришлось изменить:
функция сохранения
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;
}