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 :

Lire fichier binaire dans une classe


Sujet :

C#

  1. #1
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut Lire fichier binaire dans une classe
    Bonjour

    Je m'interroge sur la maniere la plus rationnelle de transfere un Stream dans une classe sachant que le stream contient l'image de la classe

    Pour le moment je travaille en deux phases :
    1- Je lit le stream depuis un Fichier a l'aide d'un StreamReader et je recupere un array de bytes
    2- Je transfere l'array de byte au constructeur de ma classe qui instancie un BinaryReader et un MemoryStream pour transferer le contenu du Byte[] dans chaque element de ma

    Je suis preneur de toutes propositions plus rationelle pour la conversion du Byte[] si c'est possible !

    Merci de votre aide

    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
      public class C_GData
      {
        public UInt32 PSN;
        public byte[] HMS;
        public byte[] DMY;
        public Int32 SYNCAGE;
        public byte[] LAT;
        public byte[] LONG;
        public byte[] ALT;
        public byte NAVSTAT;
        public byte[] SOG;
        public byte[] COG;
        public byte GUS;
        public byte[] PDOP;
        public byte[] HDOP;
        public byte[] VDOP;
        public Int32 GPSDIST;
        public byte GSMSTAT;
        public byte[] MCC;
        public byte MCN;
        public byte[] GPRSIP;
        public byte[] SYSUPTIME;
        public byte[] DLOG;
        public byte[] ALARMS;
        public byte[] ADCVIN;
        public byte[] ADCVACC;
        public byte[] ADCTEMP;
        public byte IOSTAT;
        public byte[] CHANGEDSYSTEM;
        public byte[] SYSTEMFLAG;
        public byte SBN;
        public byte SWV;
        public bool isValid = true;
     
        public C_GData(byte[] BData)
        {
          Decode(BData);
        }
     
        private void Decode(byte[] BData)
        {
          using (MemoryStream bs = new MemoryStream(BData))
          {
            BinaryReader br = new BinaryReader(bs, Encoding.Default);
     
            PSN = br.ReadUInt32();
            HMS = br.ReadBytes(3);
            DMY = br.ReadBytes(4);
            SYNCAGE = br.ReadInt32();
            LAT = br.ReadBytes(4);
            LONG = br.ReadBytes(5);
            ALT = br.ReadBytes(3);
            NAVSTAT = br.ReadByte();
            SOG = br.ReadBytes(3);
            COG = br.ReadBytes(3);
            GUS = br.ReadByte();
            PDOP = br.ReadBytes(2);
            HDOP = br.ReadBytes(2);
            VDOP = br.ReadBytes(2);
            GPSDIST = br.ReadInt32();
            GSMSTAT = br.ReadByte();
            MCC = br.ReadBytes(2);
            MCN = br.ReadByte();
            GPRSIP = br.ReadBytes(4);
            SYSUPTIME = br.ReadBytes(5);
            DLOG = br.ReadBytes(2);
            ALARMS = br.ReadBytes(4);
            ADCVIN = br.ReadBytes(2);
            ADCVACC = br.ReadBytes(2);
            ADCTEMP = br.ReadBytes(2);
            IOSTAT = br.ReadByte();
            CHANGEDSYSTEM = br.ReadBytes(4);
            SYSTEMFLAG = br.ReadBytes(8);
            SBN = br.ReadByte();
            SWV = br.ReadByte();
          }
        }

  2. #2
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2008
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2008
    Messages : 97
    Points : 143
    Points
    143
    Par défaut
    Bonjour,

    "L'image de ta classe"... ça ressemble fort a de la sérialisation.

    Ca dépend d'où provient ton fichier binaire mais si ton but est de sauver l'état d'un objet puis de le restituer je te conseille de le sérialiser et désérialiser avec le framework plutot que de réinventer la roue.

    Pour rendre une classe sérialisable il suffit juste d'ajouter un attribut en haut de ton nom de classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [Serializable]
    public class C_GData
    {
        ...
    }
    Et ta classe doit contenir un constructeur vide

    Pour sérialiser:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    IFormatter formatter = new BinaryFormatter();
    using(Stream stream = new FileStream("save.bin", FileMode.Create, FileAccess.Write, FileShare.None))
    {
    formatter.Serialize(stream, obj);
    }
    où obj et ton objet C_GData

    Pour désérialiser:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    IFormatter formatter = new BinaryFormatter();
    using(Stream stream = new FileStream("save.bin", FileMode.Open, FileAccess.Read, FileShare.Read))
    {
    C_GData obj = (C_GData) formatter.Deserialize(stream);
    }
    si tu n'as pas d'autres choix que de passer par ton tableau de byte, je ne chargerais pas ta classe de faire la transformation elle même, je traiterais le tableau de byte dans une autre classe.
    En plus, à ta place je typerais mes propriétés plutôt que de trainer des petit tableaux de bytes. DateTime pour HMS et DMY par ex...

  3. #3
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Mercio mkl238

    Mais tes propositions malheusement ne s'appliquent pas au contexte

    1- Je recois les données telle que présentées et sans sérialization préalable
    2- Mes petits tableaux de byte permettent de conserver une classe donnant l'mage exacte de ce que je reçoit, les transformation ultérieures, c'est un autre sujet !

    Si javais du faire cela en C j'aurais fais un bete memmove d'un buffer de lecture vers une structure

    Mais nous sommes en C#

  4. #4
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    En fait si tu utilises une structure et non une classe tu peux utiliser la fonction Marshal.PtrToStructure.

  5. #5
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Merci Meziantou

    Effectivement tu a raison
    Mais je me demande si in fine ce n'est pas aussi bricoleux que ma solution de base

    1- Parce que que je dois declarer un IntPtr
    2- allouer la memoire, sur ce InPtr
    3- faire une premiere Marshal.copy de mon Byte[] vers la memoire allouée
    4- faire un Marshall.PtrToStruct vers ma Structure
    5- Enfi, liberer la memoire alloué

    Et in fine me retrouver avec une structure plutot qu'une classe

    Je pense donc que ta proposition serait la solution mais en réalité ce ne sera pas plus efficace ni plus lisible !

Discussions similaires

  1. Réponses: 4
    Dernier message: 23/09/2010, 15h17
  2. [Framework] Injecter un fichier properties dans une classe de constante
    Par Slyders dans le forum Spring
    Réponses: 0
    Dernier message: 25/03/2010, 17h10
  3. Réponses: 1
    Dernier message: 22/03/2010, 15h40
  4. chemin vers fichiers/répertoire dans une classe
    Par Xunil dans le forum Langage
    Réponses: 5
    Dernier message: 13/04/2007, 10h14
  5. Réponses: 3
    Dernier message: 19/02/2007, 23h01

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