Partage
  • Partager sur Facebook
  • Partager sur Twitter

Lecture .txt dans un QByteArray

Lecture .txt dans un QByteArray

    12 janvier 2021 à 17:15:18

    Bonjour, il y a quelque temps j'avais posté un message dans le quel je montrais un code qui me permettait de lire le contenue d'un fichier texte ou CSV, de split les lignes et de ranger chaque valeur ainsi obtenue dans le QVector correspondant.

    Voici le morceau de code en question :

    int nb_courbes = getNbCourbes() // entre 3 et 5 en principe
    QVector<double> time;
    QVector<QVector<double>> values;
    for(int i = 0; i < nb_courbes; i++)
        values.push_back(QVector<double>); // Je fais un sous tableau pour chacune de mes datas
     
    void getDatasFromFile(const QString &path) {
        // J'ouvre mon fichier et créer un flux
        QTextStream stream(&file);
        QStringList cutLine;
        QString line = cutLine = stream.readline();
     
        while(!stream.atEnd()) {
            cutLine = stream.readline().split(','); // Je récupère le temps + la valeur de chaque grandeur mesurée
            time.push_back(cutLine[0])
            for(int i = 0; i < nb_courbes; i++)
                values[i].push_back(cutLine[i+1]);
            cutLine = stream.readline().split(',');
        }
    }     

    On m'avait alors fait les remarques suivantes et proposition suivantes :

    • Lecteur ligne par ligne ==> latence ==> Lecture de tous les fichier d'un seul coup à préférer 
    • Utilisation de split sur un QString ==> Création de plusieurs QString, c'est long
    • QString c'est du UTF-16 donc chaque caractèreest apparemment converti de char à UTF-16 ==> copie + conversions ==> perfs bonnes à jeter à la poubelle 

    On m'avait conseillé de passer par QByteArray en lisant tout le fichier d'un coup. Je m'y suis enfin collé et j'ai écrit un code très minimal pour tester ma solution en console. Le code que j'ai écrit marche, ça donne exactement ce que j'attends mais comme je ne suis pas du tout familier avec QByteArray, j'aimerais juste l'avis des personnes plus expérimentées que moi pour me dire si j'ai employé la bonne méthode vu que je vais travailler avec des fichiers qui contiennent vraiment beaucoup de data. Je ne suis pas persuadé de l'efficacité de l'utilisation successive de split qui me créer pleins de sous QByteArray ...

    Voici le nouveau code en question : 

    #include <QCoreApplication>
    #include <QDebug>
    
    #include <QFile>
    #include <QByteArray>
    #include <QVector>
    
    QByteArray readFile(const QString &path);
    void fillVector(const QByteArray &arr, QVector<double> &xVec, QVector<QVector<int>> &yVec);
    
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QString PATH = "C:\\Users\\thibault.venot\\Documents\\Soft plotCurves\\dataFile\\testByteArray.txt";
        int nbCurves{4};  // Normalement obtenue par lecture d'un fichier de config
    
    
        QVector<double> time{};
        QVector<QVector<int>> value{};
    
        for(int i = 0; i < nbCurves; i++)
            value.push_back(QVector<int>{});
    
        QByteArray myArr = readFile(PATH);
    
        fillVector(myArr,time,value);
    
    
        // Pour tester si j'ai bien lu et stocké tous les temps de mon fichier dans le QVector
        for(int i = 0; i < time.size(); i++) {
            qDebug() << time[i];
        }
    
        return a.exec();
    }
    
    
    QByteArray readFile(const QString &path)
    {
        QFile file(path);
        if(file.exists()) {
            if(file.open((QIODevice::ReadOnly))) {
                qDebug() << "open";
                return file.readAll();
            }
            else
                qDebug() << "Not open";
        }
        else
            qDebug() << "Doesn't exists";
    
        return QByteArray();
    }
    
    
    void fillVector(const QByteArray &arr, QVector<double> &xVec, QVector<QVector<int>> &yVec)
    {
        if(arr.isEmpty())
        {
            qDebug() << "QByteArray est vide";
            return;
        }
    
        QList<QByteArray> lines = arr.split('\n'); // On décompose en ligne
        QList<QByteArray> cutLine{};
    
        int taille = yVec.size() + 1;
    
        for(auto ligne : lines) {
            cutLine = ligne.split(',');
    
            if(cutLine.count() == taille)   // Ca ignore la première ligne qui ne correspond pas
            {
                xVec.push_back(cutLine[0].toDouble());
                for(int i = 0; i < taille-1; i++)
                {
                    yVec[i].push_back(cutLine[i+1].toInt());
                }
            }
        }
    }

    Précision, les datas à lire sont dans des fichiers .txt ou .csv sous cette forme avec plusieurs millions de lignes :

    Temps(s);Raw_Value;Hand_Detected;Real_Impedance;ERR_ST_HOD
    0.102,24,0,0,0
    0.199,23,0,0,0
    0.402,24,0,0,0
    0.5,23,0,0,0
    0.703,24,0,0,0
    0.801,23,0,0,0
    1.602,24,0,0,0
    1.699,23,0,0,0
    1.902,24,0,0,0
    2,23,0,0,0
    2.801,24,0,0,0
    3.102,23,0,0,0
    3.203,24,0,0,0
    3.402,23,0,0,0
    3.801,24,0,0,0


    Je précise aussi que je n'ai pas le choix sur le format des datas, ça restera présenté sous cette forme et ça restera du .txt ou du .csv

    Merci d'avance :)

    -
    Edité par ThibaultVnt 15 janvier 2021 à 8:33:19

    • Partager sur Facebook
    • Partager sur Twitter
      15 janvier 2021 à 8:40:48

      Bonjour, je me permet de up un petit peu le sujet 

      Je voudrais juste un petit avis sur la fonction fillVector puisque je connais mal la classe QByteArray et je ne sais pas si ma méthode est la bonne 

      Merci d'avance

      • Partager sur Facebook
      • Partager sur Twitter

      Lecture .txt dans un QByteArray

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown