Russian Qt Forum
Ноябрь 01, 2024, 18:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено] Как сохранить контейнерный класс на диск?  (Прочитано 8850 раз)
JamS007
Гость
« : Январь 05, 2010, 19:08 »

Здравствуйте,

в своей программе работаю с несколькими контейнерными классами, такими как: QList, QHash, QMultiHash. А тут мне понадобилась возможность сохранять эти контейнеры на диск с возможностью их последующего восстановления. Подскажите, пожалуйста, как правильно это сделать, может есть уже какой-нибудь проверенный метод, чтоб не изобретать велосипед?

спасибо.
« Последнее редактирование: Январь 07, 2010, 15:57 от JamS007 » Записан
BRE
Гость
« Ответ #1 : Январь 05, 2010, 19:10 »

Посмотри на QDataStream.
Записан
JamS007
Гость
« Ответ #2 : Январь 05, 2010, 19:13 »

смотрел... может я что-то неправильно делаю, но ничего не сохраняется (как мне кажется) вот код:

Код:
QFile file(path + fileName + databaseFormat);
    if (file.open(QIODevice::WriteOnly))
    {
        QDataStream stream(&file);
        stream.setVersion(QDataStream::Qt_4_6);
        stream << studentsList // QList<QString>
               << marksList //QMultiHash<QString, QHash<int,char> >
               << themes //QHash<QString>
               << remind //QHash<QString>
               << materials; //QHash<QString>
        if (stream.status() == QDataStream::Ok) return true;
    }
    //отправить отчет в ErrorStack

    // ...
    #ifdef QT_DEBUG
    qDebug() << "DataModel::saveDatabase - error";
    #endif
    return false;
« Последнее редактирование: Январь 05, 2010, 19:16 от JamS007 » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #3 : Январь 05, 2010, 19:18 »

>>но ничего не сохраняется (как мне кажется)
ну ты файл открой текстовом редакторе и посмотри, есть там что-нибудь или нет.
Ну и попробуй программно загрузить
Записан

Юра.
JamS007
Гость
« Ответ #4 : Январь 05, 2010, 19:23 »

Именно так и делаю. При каждом открытии файла там оказывается только 5 нечитаемых символов. причём это не зависит от количества записей в контейнере, будь их хоть 100, там все равно окажется 5 нечитаемых символов. А размер файла всегда равен 1 кб.
Записан
niXman
Гость
« Ответ #5 : Январь 05, 2010, 19:26 »

http://www.boost.org/doc/libs/1_41_0/libs/serialization/doc/index.html
Записан
BRE
Гость
« Ответ #6 : Январь 05, 2010, 19:33 »

Именно так и делаю. При каждом открытии файла там оказывается только 5 нечитаемых символов. причём это не зависит от количества записей в контейнере, будь их хоть 100, там все равно окажется 5 нечитаемых символов. А размер файла всегда равен 1 кб.
Интересно, 5 не читаемых символов размером в 1 Кб. Попробуй прочитать этот файл с использованием QDataStream, станет ясно сохраняется что-то или нет.
Коллекции сохраняются в бинарном формате, читать их как текст вряд-ли получиться.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #7 : Январь 05, 2010, 20:00 »

всё должно быть нормально, вот тест:
Код
C++ (Qt)
#include <QtGui>
 
int main(int argc, char* argv[])
{
{
QList<QString> stringList;
QList<int> intList;
stringList << "one" << "two";
intList << 1 << 2;
QFile f("./out.bin");
if (f.open(QIODevice::WriteOnly)){
QDataStream stream(&f);
stream << stringList
 << intList;
if (stream.status() != QDataStream::Ok){
qDebug() << "Write error";
return 1;
}else{
qDebug() << "Write successfully complete";
}
}else{
qDebug() << "Unable to open file";
return 1;
}
}
 
// -------------------
{
QList<QString> stringList;
QList<int> intList;
QFile f("./out.bin");
if (f.open(QIODevice::ReadOnly)){
QDataStream stream(&f);
stream >> stringList
 >> intList;
if (stream.status() != QDataStream::Ok){
qDebug() << "Read error";
return 1;
}
qDebug() << "-------";
qDebug() << "stringList:\n" << stringList;
qDebug() << "intList:\n" << intList;
}else{
qDebug() << "Unable to open file";
return 1;
}
}
   return 0;
}
 
 
 
Записан

Юра.
JamS007
Гость
« Ответ #8 : Январь 05, 2010, 20:10 »

Мда... похоже надо будет выдумать велосипед, так как:

Цитата: from assistant
Reading and writing other Qt classes.

In addition to the overloaded stream operators documented here, any Qt classes that you might want to serialize to a QDataStream will have appropriate stream operators declared as non-member of the class:

 QDataStream &operator<<(QDataStream &, const QXxx &);
 QDataStream &operator>>(QDataStream &, QXxx &);
For example, here are the stream operators declared as non-members of the QImage class:

 QDataStream & operator<< (QDataStream& stream, const QImage& image);
 QDataStream & operator>> (QDataStream& stream, QImage& image);
To see if your favorite Qt class has similar stream operators defined, check the Related Non-Members section of the class's documentation page.

2 lit-uriy: у класса QList<T> есть Related Non-Members
Цитировать
QDataStream & operator<< ( QDataStream & out, const QList<T> & list )
QDataStream & operator>> ( QDataStream & in, QList<T> & list )

а класса QHash<K,T> их нету. И соответственно, готового оператора для записи через QDataStream нету. Грустный
Записан
uriel
Гость
« Ответ #9 : Январь 05, 2010, 20:13 »

А как тогда Ваш первый пример вообще скомпилировался? Улыбающийся
Всё есть.
Цитировать
QDataStream &   operator<< ( QDataStream & out, const QHash<Key, T> & hash )
QDataStream &   operator>> ( QDataStream & in, QHash<Key, T> & hash )
Записан
JamS007
Гость
« Ответ #10 : Январь 05, 2010, 20:17 »

да... действительно... сделал поспешный вывод.  Буду искать решение дальше.



Нашел решение. Дело в том, что если создавать и инициализировать контейнерные классы динамически
Код:
 QMultiHash<QString, QHash<unsigned int, unsigned char> > *marksList;
//...
marksList    = new QMultiHash<QString, QHash<unsigned int, unsigned char> >();

то при сохранении на диск нужно использовать оператор <*> перед указателем, пример

Код:
QDataStream stream(&file);
        stream.setVersion(QDataStream::Qt_4_6);
        stream << *marksList;

а если передавать сам указатель или разыменованый указатель (&), то на диск сохраниться как раз таки указатель... (Если я правильно понял)
« Последнее редактирование: Январь 07, 2010, 15:56 от JamS007 » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.17 секунд. Запросов: 23.