Qt. Как сериализовать объекты содержащие коллекции? В общем имеются вот такие вот классы:class Institution //Класс "учебное заведение" { ... private: ... QList Pupils; //Коллекция учеников }; class Pupil //Класс "ученик" { ... private: ... QList Lessons; //Коллекция предметов }; class Exam //Класс "экзамен" { ... }; Необходимо сериализовать коллекцию объектов класса Institution (хотя я не уверена уместно ли называть это сериализацией), а именно сохранить это коллекцию в бинарник и потом "взять" её от туда. Сохранение (здесь проблем нет, т. е. sizeof работает как надо):QList institutions; ... Institution bf("", 0); char str[1024]; strcpy(str, filename.toStdString().c_str()); std::ofstream out(str, std::ios::out | std::ios::binary); for (int i = 0; i institutions; ... institutions.clear(); char str[1024]; strcpy(str, filename.toStdString().c_str()); std::ifstream in(str, std::ios::in | std::ios::binary); while (!in.eof() && in.peek() != EOF) { Institution *bf = new Institution("", 0); int a = sizeof bf; in.read((char *) bf, sizeof *bf); //! institutions.append(bf); } in.close(); Теперь и вопрос, как всё-таки можно записать и считать эту коллекцию в/из бинарника, не изменяя структуру классов(!)? Или может быть есть что-то подобное как в Java?/*Коллекция*/ ArrayList list = new ArrayList(); /*Запись*/ try { FileOutputStream fos = new FileOutputStream(file.toString()); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(list); oos.close(); fos.close(); } catch(IOException ioe) { } /*Считывание*/ FileInputStream fis = new FileInputStream(file.toString()); ObjectInputStream ois = new ObjectInputStream(fis); try { list = (ArrayList) ois.readObject(); } catch (ClassNotFoundException e) { } ois.close(); fis.close();
Для сериализации объектов содержащих коллекции в Qt, можно воспользоваться классом QDataStream. Например, для сохранения коллекции учебных заведений в бинарный файл можно воспользоваться следующим кодом:
QList<Institution *> institutions; // добавление учебных заведений в коллекцию QFile file("filename.bin"); if (file.open(QIODevice::WriteOnly)) { QDataStream out(&file); out << institutions.size(); for (int i = 0; i < institutions.size(); i++) { out << *institutions[i]; } file.close(); }
И для чтения коллекции из бинарного файла:
QList<Institution *> institutions; QFile file("filename.bin"); if (file.open(QIODevice::ReadOnly)) { QDataStream in(&file); int size; in >> size; for (int i = 0; i < size; i++) { Institution *institution = new Institution("", 0); in >> *institution; institutions.append(institution); } file.close(); }
Для того чтобы объекты классов Institution, Pupil и Exam могли быть сериализуемыми с помощью QDataStream, необходимо определить операторы << (для записи) и >> (для чтения) для каждого класса. Например:
QDataStream &operator<<(QDataStream &out, const Institution &institution) { out << institution.Pupils.size(); for (int i = 0; i < institution.Pupils.size(); i++) { out << *institution.Pupils[i]; } return out; } QDataStream &operator>>(QDataStream &in, Institution &institution) { int size; in >> size; for (int i = 0; i < size; i++) { Pupil *pupil = new Pupil(); in >> *pupil; institution.Pupils.append(pupil); } return in; } // Аналогично для классов Pupil и Exam
Таким образом, вы можете сохранить и загрузить коллекцию объектов содержащих коллекции из бинарного файла, не изменяя структуру классов.
Для сериализации объектов содержащих коллекции в Qt, можно воспользоваться классом QDataStream.
QList<Institution *> institutions;Например, для сохранения коллекции учебных заведений в бинарный файл можно воспользоваться следующим кодом:
// добавление учебных заведений в коллекцию
QFile file("filename.bin");
if (file.open(QIODevice::WriteOnly)) {
QDataStream out(&file);
out << institutions.size();
for (int i = 0; i < institutions.size(); i++) {
out << *institutions[i];
}
file.close();
}
И для чтения коллекции из бинарного файла:
QList<Institution *> institutions;QFile file("filename.bin");
if (file.open(QIODevice::ReadOnly)) {
QDataStream in(&file);
int size;
in >> size;
for (int i = 0; i < size; i++) {
Institution *institution = new Institution("", 0);
in >> *institution;
institutions.append(institution);
}
file.close();
}
Для того чтобы объекты классов Institution, Pupil и Exam могли быть сериализуемыми с помощью QDataStream, необходимо определить операторы << (для записи) и >> (для чтения) для каждого класса. Например:
QDataStream &operator<<(QDataStream &out, const Institution &institution){
out << institution.Pupils.size();
for (int i = 0; i < institution.Pupils.size(); i++) {
out << *institution.Pupils[i];
}
return out;
}
QDataStream &operator>>(QDataStream &in, Institution &institution)
{
int size;
in >> size;
for (int i = 0; i < size; i++) {
Pupil *pupil = new Pupil();
in >> *pupil;
institution.Pupils.append(pupil);
}
return in;
}
// Аналогично для классов Pupil и Exam
Таким образом, вы можете сохранить и загрузить коллекцию объектов содержащих коллекции из бинарного файла, не изменяя структуру классов.