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

Langage Delphi Discussion :

[arbre] Sauvegarder un objet dans un fichier


Sujet :

Langage Delphi

  1. #1
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut [arbre] Sauvegarder un objet dans un fichier
    Je me suis crée une classe arbre.
    J'ai donc créé un arbre avec plusieurs branches.

    Je vourdrais sauvegarder cette arbre dans un fichier et pouvoir le recharger facilement.
    Je ne sais pas si c'est possible en delphi.
    peut-être avec TCustomMemoryStream mais je ne sais pas trop comment m'en servir.

    Certains composants ont la méthode saveToFile ou saveToStream. Est-ce qu'il faut que je reprogramme ces fonctions dans ma classe ?

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 61
    Points : 63
    Points
    63
    Par défaut
    Bonjour à toi Diedie

    Pour cela il faut passer par les flux
    En effet tous les composants de la VCL peuvent ètre sauvegarder
    dans un flux puis ensuite, dans un fichier par l'intermédiaire d'un
    TFileStream

    Voici un exemple qui permet de sauvegarder dans un fichier un TButton
    que tu aura placer préalablement dans ta fiche.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    //Pour Sauvegarder un composant dans un fichier via un flux
    // Exemple avec un TButton de ta fiche
    procedure TForm1.SaveObjet;
    var
      Data : TFileStream;
    begin
       Data:= TFileStream.Create('MonFichier.dat', fmCreate);
       Data.WriteComponent(Button1);
       Data.Free;
    end;
    Pour Lire le comosant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // Pour Extraire le composant depuis le fichier
    procedure TForm1.LoadObjet;
    var
      Data: TFileStream;
      Obj : TComponent;
    begin
        Data:= TFileStream.Create('MonFichier.dat', fmOpenRead);
        Obj:= Data.ReadComponent(Button1);
        Button1:= Obj as TButton;
        Data.Free;
    end;
    Voila

    @+ Laurent
    C++ BUILDER & DELPHI

  3. #3
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    J'ai un problème, ma classe n'hérite de rien du tou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    type  ArbreOuverture=class
     
      public
        pere:integer;
      listfils:TList;
      procedure add(Fils:Integer);
      constructor create(Noeud:Integer); overload;
      procedure AjouterListe(ListNoeud:TList;index:integer);
      function Recherche(ListNoeud:TList;index:integer):integer;
      end;
    Donc, si j'utilise Data.WriteComponent, j'ai l'erreur suivante
    [Erreur] Unit1.pas(2468): Types incompatibles : 'TComponent' et 'ArbreOuverture'

    par contre, si je mets

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    type  ArbreOuverture=class(TComponent)
    ça compile, mais mon fichier sauvegardé ne fait que 22 octets et contient:
    TPF0ArbreOuverture

    alors que mon arbre à 6 niveaux.

  4. #4
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    Est-ce que le problème pourrait venir que mon objet est en fait un objet récursif (Un arbre contient un noeud et un arbre-fils) ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 61
    Points : 63
    Points
    63
    Par défaut
    Bonsoir à toi Diedie

    Effectivement, si ta classe n'est pas descendante de TComponent,
    ça ne marchera pas !!!
    Dans ce cas, il faut imperativement dériver ta classe de TComponent
    mais ce n'est pas tous il te faudra surcharger certaines méthodes et cela risque d'ètre fastidieux !!

    Pour info, pourquoi n'utilise tu pas un TTreeView ou alors définir ta classe
    ArbreOuverture de TTreeView ?
    ce serai certainement beaucoup plus simple je pense

    A+ Laurent
    C++ BUILDER & DELPHI

  6. #6
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    Finalement, je pense recréer la fonction savetofile dnas ma classe

    Ce que je fait, je copie dans le fichier le numéro du noeud(1 ou 2 chiffres)
    Puis je copie le nombre de fils (1 ou 2 chiffres)
    Enfin je recopie récusrsivement le reste

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure ArbreOuverture.SaveToFile(Data:TFileStream);
    var
      i:Integer;
    begin
      Data.Write(pere,2*sizeof(Integer));
      Data.Write(ListFils.count,2*sizeof(Integer));
      for i:=0 to ListFils.count-1 do
        ArbreOuverture(ListFils[i]).SaveToFile(Data);
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure ArbreOuverture.LoadFromFile(Data:TFileStream);
    var
      i:Integer;
      a,b:Integer;
    begin
      Data.Read(a,2*sizeof(Integer));
      Data.Read(b,2*sizeof(Integer));
      add(a);
      for i:=0 to b-1 do
        ArbreOuverture(ListFils[i]).LoadFromFile(Data);
    end
    ;

    Par contre, je ne sais pas trop comment marche la fonction Write et Read
    Si ça marche (je suis en phase de test), je mets résolu

  7. #7
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    Merci pour ton aide Lolo

    Après correction et tests, ça marche. Voilà un exemple de code pour une classe arbre si ça intéresse quelqu'un un jour (j'ai quand même lu quelques questions sur les arbres sur le forum)

    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
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    unit Unit2;
     
    interface
     
    uses classes, comctrls;
     
    type  ArbreOuverture=class
     
      public
        pere:integer;
      listfils:TList;
      procedure add(Fils:Integer);
      constructor create(Noeud:Integer); overload;
      procedure AjouterListe(ListNoeud:TList;index:integer);
      procedure SaveToFile(Data:TFileStream);
      procedure LoadFromFile(Data:TFileStream);
      function Recherche(ListNoeud:TList;index:integer):integer;
      end;
     
    implementation
     
    constructor ArbreOuverture.create(Noeud:Integer);
    begin
      Pere:=Noeud;
      ListFils:=TList.Create;
    end;
     
    procedure ArbreOuverture.add(Fils:Integer);
    var
      Arbreaajouter:ArbreOuverture;
    begin
       Arbreaajouter:=ArbreOuverture.Create(Fils);
       listfils.Add(arbreaajouter);
    end;
     
    procedure ArbreOuverture.AjouterListe(ListNoeud:TList;index:integer);
    var
      i:integer;
      bool:boolean;
    begin
      bool:=false;
      if Index=ListNoeud.count then exit;
       for i:=0 to Listfils.Count-1 do
          if ArbreOuverture(ListFils[i]).Pere=Integer(ListNoeud[index]) then begin bool:=true; break; end;
       if bool  then ArbreOuverture(ListFils[i]).AjouterListe(ListNoeud,index+1)
          else
          begin
          add(Integer(ListNoeud[index]));
          ArbreOuverture(ListFils[ListFils.count-1]).AjouterListe(ListNoeud,index+1);
          end;
    end;
     
    //Recherche le noeud suivant (qui dans mon cas est forcément unique)
    function ArbreOuverture.Recherche(ListNoeud:TList;index:Integer):Integer;
    var
      i:integer;
     
    begin
      if index=ListNoeud.count then
          begin
          result:=ArbreOuverture(ListFils[0]).pere;
          exit;
          end;
     
      for i:=0 to ListFils.count-1 do
        if Integer(ArbreOuverture(ListFils[i]).pere)=Integer(ListNoeud[index]) then break;
     
      result:=ArbreOuverture(ListFils[i]).recherche(ListNoeud,index+1);
    end;
     
    procedure ArbreOuverture.SaveToFile(Data:TFileStream);
    var
      i:Integer;
    begin
      Data.Write(pere,sizeof(integer));
      Data.Write(ListFils.count,sizeof(integer));
      for i:=0 to ListFils.count-1 do
        ArbreOuverture(ListFils[i]).SaveToFile(Data);
    end;
     
    procedure ArbreOuverture.LoadFromFile(Data:TFileStream);
    var
      i:Integer;
      a,b:Integer;
    begin
      Data.Read(a,sizeof(integer));
      Data.Read(b,sizeof(integer));
      add(a);
      for i:=0 to b-1 do
        ArbreOuverture(ListFils[ListFils.count-1]).LoadFromFile(Data);
    end;
     
    end.

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

Discussions similaires

  1. Meilleure façon de sauvegarder un objet dans un fichier ?
    Par piotrr dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 29/10/2008, 11h40
  2. Réponses: 5
    Dernier message: 21/10/2005, 11h48
  3. [C#] Sauvegarde de texture dans un fichier + transparence
    Par Harry_polin dans le forum DirectX
    Réponses: 13
    Dernier message: 23/07/2005, 18h12
  4. Sauvegarder une surface dans un fichier
    Par Freakazoid dans le forum DirectX
    Réponses: 6
    Dernier message: 18/08/2002, 15h23

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