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 :

[WIN32][D7] Question sur TStream et TPersistent


Sujet :

Langage Delphi

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut [WIN32][D7] Question sur TStream et TPersistent
    Bonjour à tous,

    Voici ma situation : Je désire écrire les objets complexes (contenant différents objets eux-mêmes ou des listes d'objets) dans un fichier binaire.

    Comme plusieurs d'entre-vous le savez déjà, il existe de plusieurs façons d'écrire dans un fichier binaire. Delphi étant très axé "components writing" (tel que dans un .DFM) et que mes objets ne sont pas des composants, j'ai cherché sur google, les newsgroup, les forums (incluant celui-ci) et l'aide de Delphi pour un moyen détourné.

    Dans l'aide de Delphi, j'ai trouvé un exemple qui utilise les méthodes :
    WriteComponentResFile
    et
    ReadComponentResFile

    L'exemple crée une classe container contenant l'objet dans une property publié (published - seuls les property published sont streamer).

    Puis l'exemple crée une autre classe appelé : TStreamableClass qui va publié le conteneur. Ces classes sont enregistrés ( RegisterClasses() ) afin que le RTTI (Run Time Type Information) puisse les reconnaître et les traitées.

    L'exemple fonctionne très bien et les attributs membres de type integer et string sont écrits et lus. Cependant, si j'ajoute un objet dans la classe TContainer, en prenant soin de placer la property dans la section published et enregistrer la classe et cette classe hérite de TPersistent (pour qu'elle soit streamer) et les property de cette classe dans la section published.... l'objet n'est pas lu. Je ne sais pas si l'objet est écrit ou non.

    Voici l'exemple de l'aide de Delphi que j'ai modifié (3 units):

    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
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
     
    {Dans la form. ajouté un bouton et ajouté dans l'event OnClick la procédure ci-dessous}
     
    unit ProjetStreamExemple;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, StrmExmpl;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      AClassInstance: TStreamableClass;
    begin
      AClassInstance := TStreamableClass.Create(nil);
      WriteComponentResFile('C:\Test', AClassInstance);
      FreeAndNil(AClassInstance);
     
      AClassInstance := ReadComponentResFile('C:\Test', nil) as TStreamableClass;
      FreeAndNil(AClassInstance);
    end;
     
    end.
     
    //------------------------------------
    unit StrmExmpl;
    {$R-,T-,H+,X+}
     
    interface
     
    uses Classes, Test;
     
    type
     
      TContainedClass = class(TPersistent)
        private
        FSomeData: Integer;
        FSomeTest : TTest;
        SSomeString : string;
        procedure SetSomeData(Value: Integer);
        procedure SetSomeTest(Value: Ttest);
        function LireSomeTest: Ttest;
        procedure SetSomeString(const Value: string);
     
        public
     
        constructor Create;
     
        // Seules les propriétés publiées
        // sont mises automatiquement dans le flux.
        published
     
        property SomeData: Integer read FSomeData write SetSomeData;
        property SomeTest: Ttest read LireSomeTest write SetSomeTest;
        property SomeString : string read SSomeString write SetSomeString;
      end;
     
     
      TStreamableClass = class(TComponent)
        private
        FContainedClass: TContainedClass;
        public
        constructor Create(AOwner: TComponent); override;
     
     
        destructor Destroy; override;
     
        // Seules les propriétés publiées
        // sont mises automatiquement dans le flux.
        published
     
        property ContainedClass: TContainedClass read FContainedClass write FContainedClass;
     
      end;
     
    implementation
     
    procedure TContainedClass.SetSomeData(Value: Integer);
    begin
    { Placer un point d'arrêt ici et remarquer comment les données reviennent dans le flux. }
      FSomeData := Value;
    end;
     
    procedure TContainedClass.SetSomeTest(Value: Ttest);
    begin
      FSomeTest := Value;
    end;
     
    constructor TContainedClass.Create;
    begin
      FSomeData := 42;
      SSomeString := 'Adam';
      FSomeTest := TTest.create;
    end;
     
    constructor TStreamableClass.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FContainedClass := TContainedClass.Create;
    end;
     
    destructor TStreamableClass.Destroy;
    begin
      FContainedClass.Free;
    end;
     
    function TContainedClass.LireSomeTest: Ttest;
    begin
      Result := FSomeTest;
    end;
     
    procedure TContainedClass.SetSomeString(const Value: string);
    begin
      SSomeString := Value;
    end;
     
    initialization
      RegisterClasses([TContainedClass, TTest, TStreamableClass]);
    finalization
     
    end.
     
    //-------------------------------------------------------------------------------
    unit Test;
     
    interface
     
    uses Classes;
     
    type
      Ttest = class(TPersistent)
      private
        fValue : string;
        sValue : integer;
        function ReadValue1: string;
        function ReadValue2: integer;
        procedure WriteValue1(const Value: string);
        procedure WriteValue2(const Value: integer);
      public
        constructor Create;
      published
        property Value1 : string read ReadValue1 write WriteValue1;
        property Value2 : integer read ReadValue2 write WriteValue2;
      end;
     
    implementation
     
    { Ttest }
     
    constructor Ttest.Create;
    begin
      inherited create;
      fValue := 'Adam';
      sValue := 1;
    end;
     
    function Ttest.ReadValue1: string;
    begin
      Result := fValue;
    end;
     
    function Ttest.ReadValue2: integer;
    begin
      Result := sValue;
    end;
     
    procedure Ttest.WriteValue1(const Value: string);
    begin
      fValue := Value;
    end;
     
    procedure Ttest.WriteValue2(const Value: integer);
    begin
      sValue := Value;
    end;
     
    end.
    Ma question est la suivante : est-ce qu'il est possible d'écrire et de lire l'objet de la classe TTest selon cette méthode ?

    Je ne peux pas utilisé les TCollections et TCollectionItem car dans mon programme principal (pas cet exemple), les objets contiennent une liste d'objets différents.

    J'aimerais pouvoir éviter d'écrire chaque objet individuellement en créant des nouvelles fonctions de streaming, spécifiant la taille des string, integer et autre avant.... à cause de la complexité du programme principal.

    Merci à l'avance,

    Andalarius

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    No one got an idea ?

    Andalarius

  3. #3
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bjr,

    Ton code me semble tout à fait correct ...

    Sauf que je n'utilise jamais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      RegisterClasses([TContainedClass, TTest, TStreamableClass]);
    mais directement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure Register;
    begin
      RegisterComponents('Exemple',[TStreamableClass]);
    end;
    et d'habitude ca suffit



    @+
    Php
    @+
    Php

    D7 Enterprise - XP sp2
    The Truth is Out There

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Je voulais dire, est-ce qu'il est possible de lire l'objet Test après l'avoir écrit dans le fichier binaire ? car le code fournit ci-haut ne fonctionne pas pour lire l'objet après.

    Andalarius

  5. #5
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bjr,

    A autant pour moi, j'avais zappé le pb du WriteComponentResFile

    Ben ca fonctionne chez moi (manque qd même quelques inherited ici ou là dans le Destroy par ex)

    En fait si tu appelles ton fichier de sortie "test.dfm" tu peux l'ouvrir directement dans Delphi et lire son contenu

    Eh oui ton fichier binaire est un dfm ...

    Voilà

    @+
    Php
    @+
    Php

    D7 Enterprise - XP sp2
    The Truth is Out There

Discussions similaires

  1. [debutant] Questions sur 1 futur projet
    Par cyrull22 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 28/04/2003, 21h49
  2. Quelques questions sur le TWebBrowser...
    Par CorO dans le forum Web & réseau
    Réponses: 3
    Dernier message: 17/01/2003, 21h23
  3. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  4. Réponses: 2
    Dernier message: 11/08/2002, 21h27
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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