IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Lecture de fichiers binaires


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut Lecture de fichiers binaires
    Bonjour

    J'ai besoin de lire des fichiers binaires qui contiennent le contenu de petites mémoires dans des systèmes d'enregistrement electroniques. La taille de ces fichiers est donc de max la taille des mémoires soit 256Mo.

    Je dois traiter ces données en partant du début du fichier et en avant byte par byte (ou plus, pour lire des int32 ou doubles si je suis sur une trame de donnée) et mon problème est que ca prend une infinité de temps, plusieurs minutes sur un i7 récent, un temps insoutenable sur des plus petites machines.

    Ci dessous un des codes que j'ai fait, un des plus simple puisqu'il ne fait que tester le contenu d'un fichier de test contenant 0 1 2 3.....252 253 254 0 1 2 3....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
            private void btTesterFichierTest_Click(object sender, EventArgs e)
            {
                richTextBox2.Clear();
                long i = 0;
     
                const string fileName = "toto2.dav";
     
                if (!File.Exists(fileName))
                {
                    MessageBox.Show("Le fichier n'existe pas encore. Il faut lire la mémoire en HighPSeed");
                }
                else
                {
                    using (BinaryReader MonReader = new BinaryReader(File.Open(fileName, FileMode.Open)))
                    {
                        MonReader.BaseStream.Position = 0;
                        int ReferenceTest = 0;
     
                        int comptageAdresseReelleMemoireFlash = 0;
     
                        bool stop = false;
     
                        while (MonReader.BaseStream.Position < MonReader.BaseStream.Length && stop == false)
                        {
     
                            if (comptageAdresseReelleMemoireFlash < 2048)
                            {
                                int valeur = MonReader.ReadByte();
                                if (valeur != ReferenceTest)
                                {
                                       stop = true;
                                    StatusProgressTextColor(100, System.Drawing.Color.LimeGreen, "TestFichier. Pos : " + (MonReader.BaseStream.Position - 1).ToString() + " ValeurAttendue :" + ReferenceTest.ToString() + " Valeur :" + valeur.ToString() + " \r\n");
                                }
                            }                       
     
     
                            ReferenceTest +=1;
                            comptageAdresseReelleMemoireFlash += 1;
                            if (ReferenceTest == 255) ReferenceTest = 0;
                            if (comptageAdresseReelleMemoireFlash == 2112) comptageAdresseReelleMemoireFlash = 0;
                        }
                    }
    Comment puis je m'y prendre pour lire mes fichiers autrement ? Une manière radicalement différente qui me permettrait d'aller infiniment plus vite ?
    Je me demandais si charger le tableau en ram serait plus rapide ? avec une crainte sur l'alignement en mémoire qui ferait que mes 256Mo prendrait 8fois plus de place sur une machine 64bit et peut être pas la même efficacité pour lire le flux (pas de readbyte, readdouble, readInt32...)

    Merci par avance pour vos conseils

  2. #2
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Par défaut
    Salut,

    j'ai eu le même souci hier (mais en C) : je devais faire du char à char sur des gros fichier et j'avais des temps d'enfants chiens femelles. Je pouvais atteindre pas loin de 7" pour une fichier de 100Mo. J'ai refait le code en full mémoire et maintenant je suis en-dessous de la seconde. Ça m'a pris moins de 5' à coder (sans casser l'existant, avec un tit #define/#ifdef semé de partout). Du coup ça vaudrait le coup pour toi de faire le test. Il faut évidemment que la machine qui fait tourner ton appli supporte la charge.

    Si les perfs sont toujours cracra faudra creuser l'opti du traitement, voire du prog en général.

  3. #3
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Je viens à l'instant de finir un test avec chargemetn en mémoire

    bonne nouvelle ,les tableaux de byte semblent ne pas souffrir de l'alignement, ca me prend trés peu de ram (les 256Mo)
    La mauvaise nouvelle c'est que le temps de traitement est encore plus long ! ca parle en minutes, prés de 5 ( 300secondes) là pour 200Mo !

    il y a forcément un truc que je fais mal
    Dans mon premier post le code avec des readbyte successif sur le fichier

    et ici le code avec un chargement dans un tableau de byte puis traitement du tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
                    using (BinaryReader MonReader = new BinaryReader(File.Open(fileName, FileMode.Open)))
                    {
                        byte[] contenu = new byte[MonReader.BaseStream.Length];
     
                        MonReader.Read(contenu, 0, (Int32)MonReader.BaseStream.Length);
     
     
                        Int32 Position = 0;
                        byte ReferenceTest = 0;
     
                        Int32 comptageAdresseReelleMemoireFlash = 0;
     
                        bool stop = false;
     
                        while (Position < MonReader.BaseStream.Length && stop == false)
                        {
     
                            if (comptageAdresseReelleMemoireFlash < 2048)
                            {
                                if (contenu[Position++] != ReferenceTest)
                                {
                                    stop = true;
                                    StatusProgressTextColor(100, System.Drawing.Color.LimeGreen, "TestFichier. Pos : " + (Position-1).ToString() + " ValeurAttendue :" + ReferenceTest.ToString() + " Valeur :" + contenu[Position -1].ToString() + " \r\n");
                                }
                            }
     
                            ReferenceTest += 1;
                            comptageAdresseReelleMemoireFlash += 1;
                            if (ReferenceTest == 255) ReferenceTest = 0;
                            if (comptageAdresseReelleMemoireFlash == 2112) comptageAdresseReelleMemoireFlash = 0;
                        }
                    }
    ça fonctionne mais c'est pire en temps de traitement !

    Merci

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Par défaut
    Bonjour,

    Evite le test sur la taille du fichier à chaque boucle en stockant sa valeur dans une variable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    long Eof = MonReader.BaseStream.Length;
    while (Position < Eof && !stop)
    {...}
    Tu vas sentir la différence !!

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    readbyte doit en effet être à éviter


    le plus simple à coder et qui devrait être déjà beaucoup plus performant c'est
    system.io.file.readAllBytes (qui retourne un tableau d'octets de tout le fichier directement)
    la lecture devrait se faire sans pause et après tu fais ton traitement sur le tableau (256Mo à lire à 20Mo/s (dd lent) ca fait une grosse dizaine de secondes))
    l'avantage aussi c'est de pouvoir utiliser le stopwatch pour savoir le temps de lecture puis le temps de traitement, et savoir lequel optimiser

    après ce qui doit etre le plus performant et qui ne prendrait pas 256Mo de ram serait de lire et de traiter le tout sur 2 threads différents (en lisant quelques Mo à la fois, à mettre dans un queue, et l'autre thread dequeue)
    mais bon de nos jours 250Mo de ram ca n'est rien (le Go étant autour de 10€ je crois) donc ca serait plus compliqué à coder mais seulement si tu veux gagner 5 secondes ^^
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Il faut que j'affine mes tests peut être entre RAM et pas RAM mais en supprimant la recherche de la taille du fichier à chaque boucle je viens de passer de 5min à 2s environ (j'ai un SSD performant)

    je savais bien que j'avais fait une énormité...

    merci beaucoup

    je vais fignoler mais la révolution est là !

    re merci

  7. #7
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    EDIT : non, rien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 09/10/2012, 09h00
  2. Réponses: 2
    Dernier message: 19/04/2011, 08h56
  3. thread ->private void exit
    Par chabacano dans le forum Concurrence et multi-thread
    Réponses: 0
    Dernier message: 03/06/2010, 19h13
  4. Identifier "object sender"
    Par koyot3 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 27/10/2008, 17h42
  5. object^ sender c++.net
    Par TrollTop dans le forum VC++ .NET
    Réponses: 1
    Dernier message: 08/07/2007, 10h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo