0

I am writting some objects in a binary file and I would like to read them back. To explain you what I am trying to do, I prepared a simple example with a class User that contains the QString name and QList name of childrens. Please see the code below.

#include "QString"
#include "QFile"
#include "QDataStream"
#include "qdebug.h"

class User
{
protected:
QString name;
QList<QString> childrens;

public:
QString getName(){ return name;}
QList<QString> getChildrens(){ return childrens;}

void setName(QString x) {name = x;}
void setChildrens(QList<QString> x) {childrens = x;}

//I have no idea of how to get the number of users in "test.db"
int countDatabase()
{

}

//I would like to read the user named "pn" without putting all users in memory
void read(QString pn)
{
    QFile fileRead("test.db");
    if (!fileRead.open(QIODevice::ReadOnly)) {
        qDebug() << "Cannot open file for writing: test.db";
        return;
    }
    QDataStream in(&fileRead);
    in.setVersion(QDataStream::Qt_5_14);
    in>>*this;
}


void write()
{
    QFile file("test.db");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
        qDebug() << "Cannot open file for writing: test.db";
        return;
    }
    QDataStream out(&file);
    out.setVersion(QDataStream::Qt_5_14);
    out<<*this;
}

friend QDataStream &operator<<(QDataStream &out, const User &t)
{
    out << t.name << t.childrens;
    return out;
}

friend QDataStream &operator>>(QDataStream &in, User &t)
{
    QString inname;
    QList<QString> inchildrens;
    in >> inname >> inchildrens;
    t.name = inname;
    t.childrens = inchildrens;
    return in;
}

};


////////////////////////////////////////////////////////////////
int main()
{
    User u;
    u.setName("Georges");
    u.setChildrens(QList<QString>()<<"Jeanne"<<"Jean");
    u.write();

    User v;
    u.setName("Alex");
    u.setChildrens(QList<QString>()<<"Matthew");
    u.write();

    User w;
    w.setName("Mario"); // no children
    w.write();

    User to_read;
    to_read.read("Alex");

    qDebug()<<to_read.getName();
    return 0;
}

I successfully write all the users I want in my binary file. However, I would like to be able, without loading everything in memory:

  • To know how many users are stored in the binary file,
  • To read a user by giving the name of this user.

I have used until now a QDataStream and I am overloading the << and >> operators for the serialization. Maybe what I want is not possible with this method. Could you please provide me some hints to succeed with QDataStream or some other methods?

froz
  • 163
  • 1
  • 12
  • If you do not want to load everything in memory I think you need to set up a header at the beginning of the file where you save the record count and then you will also need an index file or use a part of the file as a n index. But his way you are getting closer and closer to database so why do not you just use sqlite ? – Marco Feb 11 '20 at 06:48
  • I don't want to use sqlite because I don't want the data to be accessible or modified, outside of the program. – froz Feb 11 '20 at 09:57
  • In the same time, I don't know how to store a QList in a sqlite database. – froz Feb 11 '20 at 11:16

1 Answers1

0

Please find a solution here that finally did not required binary files but uses a BLOB in a SQL db:

SOLUTION

froz
  • 163
  • 1
  • 12