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 :

Type Record dans un stream


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 43
    Points : 21
    Points
    21
    Par défaut Type Record dans un stream
    Bonjour

    Sujet mainte fois débattu j'imagine.
    J'ai un composant que je streame (sauvegarde comme file) et qui possède des Type Record comme propriété placé en published. Sauf que les type Record ne sont pas streamés.
    Une suggestion, à part éclater chaque ligne de mes record en autant de propriété de type simple ?

    Merci

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    1) DefineBinaryProperty
    2) RegisterPropertyEditor
    3) remplacer le record par un dérivé TPersistent
    4) publier les différents champs du record comme des propriétés
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre à l'essai
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 43
    Points : 21
    Points
    21
    Par défaut
    OK pour le 4, c'est ce que je fais habituellement
    pour le 3, plus élégant mais faut instancier/détruire chaque objet, ce que nous épargne justement les record...
    1 et 2, un peu trop élaboré pour ce que j'ai à faire

    Merci pour ta réponse

  4. #4
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    Salut,

    Et avec WriteComponentResFile() et ReadComponentResFile() ?

  5. #5
    Membre à l'essai
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 43
    Points : 21
    Points
    21
    Par défaut
    En fait, je me demandais juste si, depuis le temps, quelqu'un avait pondu une procédure qui écrive et lise un type record dans un stream afin de rendre à peu prés transparente la persistence des Record.

    Sinon, je n'ai pas de problème à modifier mon code pour obtenir cette persistence, je trouve juste dommage que Delphi ne soit pas trés performant sur cet aspect et oblige à chaque fois à réinventer la roue.

  6. #6
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    Un Record c'est un Pointeur. Il faudrait donc automatiser ce que tu fais à la main. Ce n'est pas impossible...

    Mais dans ton cas, le plus simple serait d'utiliser une chaîne pour écrire ton compo dans le TStream.
    Voici un exemple avec un TPanel :


    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
    function CompoVersChaine(Compo : TComponent):string;
    {On utilise la gestion de flux de composant intégré pour convertir un composant en une chaîne.}
      var
          MemStrm : TMemoryStream;
          StrStrm : TStringStream;
          S       : String;
      begin
      MemStrm := TMemoryStream.Create;
      try
        StrStrm := TStringStream.Create(S);
     
        try
          MemStrm.WriteComponent(Compo);//Ecrit le Compo dans le flux TMemoryStream.
          MemStrm.Seek(0,soFromBeginning);//Se place au début du flux MemStrm.
          ObjectBinaryToText(MemStrm,StrStrm);//Convertit l'objet contenu ds MemStream en une version littérale simple et le place ds StrStrm.
          StrStrm.Seek(0,soFromBeginning);//Se place au début du flux StrStrm.
          Result := StrStrm.DataString;//On accéde au texte du flux.
        finally StrStrm.Free;  end;
     
      finally MemStrm.Free;  end;
    end;
     
     
    procedure ChaineVersCompo(Chaine : string; Compo : TComponent);
    {On utilise la gestion de flux de composant intégré pour convertir une chaîne en un composant.}
      var
          MemStrm : TMemoryStream;
          StrStrm : TStringStream;
      begin
      StrStrm := TStringStream.Create(Chaine);
      try
        MemStrm := TMemoryStream.Create;
     
        try
          ObjectTextToBinary(StrStrm,MemStrm);
          MemStrm.Seek(0,soFromBeginning);
          MemStrm.ReadComponent(Compo);
        finally MemStrm.Free; end;
     
      finally StrStrm.Free; end;
    end;
    Ecriture et lecture d'un Compo dans le flux (ici le TPanel Pnl_Conteneur).
    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
    ...
    {Ecriture du compo Pnl_Conteneur.
     NB: il sera écrit avec les compos dont il est le owner.
     L'astuce est de convertir le compo en chaîne et d'écrire cette chaîne...}
    Chaine := CompoVersChaine(Pnl_Conteneur);//Conversion...
    Taille := length(Chaine);//...puis, comme une chaîne longue.
    FileStrm.WriteBuffer(Taille,SizeOf(Taille));
    FileStrm.WriteBuffer(Chaine[1],Taille);
    ...
    {Lecture du compo Pnl_Conteneur.
     NB: il est lu comme une chaîne,
     puis cette chaîne sera convertie en compo.}
    FileStrm.ReadBuffer(Taille,SizeOf(Integer));
    SetLength(Chaine,Taille);
    FileStrm.ReadBuffer(Chaine[1],Taille);
    ChaineVersCompo(Chaine,Pnl_Conteneur);

  7. #7
    Membre à l'essai
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 43
    Points : 21
    Points
    21
    Par défaut
    En fait, j'ai déjà fait ça (transformer les données en chaine et inversement). Mais ce sont des cas particulier sur un type connu. C'est l'aspect générique qui m'interesserait sur un type quelconque (mais ce n'est peut-être pas possible avec des record, d'où la nécessité de passer par TPersistent)

    Ce n'est pas trés important, ça me prend pour l'instant dix minutes de codage supplémentaire, donc sans incidence pour moi.

    OK, je vais regarder ton code (mais pas tout de suite).

    Merci pour l'exemple

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    dans les dernières versions de Delphi, les RTTI sont disponibles à tous les niveaux...il doit être possible de génériser ça
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    il me semble que SJRD l'a déjà fait : Enregistrement de record non finalisé : ScSerializer avec les anciennes RTTI via TypInfo.GetTypeData encapsulé dans ScTypInfo en s'inspirant de Finalize \ System._FinalizeRecord qui arrive a nettoyer correctement un struct contenant un array dynamique !

    Sinon, un record avec des types simples comme ShortString, integer, array[0..1] of integer, ... peut être sérialisez brutalement
    dès que cela contient dyn array ou string, cela se complique d'où l'API de SJRD
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre à l'essai
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 43
    Points : 21
    Points
    21
    Par défaut
    Oui, j'ai vu que dans les dernières versions, les recors avaient pas mal évolué. mais là, je développe toujours avec mon antique D6.
    En tout cas merci à tous pour votre flots de réponses pertinentes. Ce forum est toujours un plaisir pour apprendre.

Discussions similaires

  1. Problème de type RECORD dans PGSQL
    Par wangying dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 29/01/2013, 16h19
  2. %ROWTYPE dans un TYPE RECORD
    Par cala dans le forum PL/SQL
    Réponses: 11
    Dernier message: 09/10/2009, 14h24
  3. Réponses: 5
    Dernier message: 07/04/2008, 09h33
  4. Type TFont dans un record
    Par dacid dans le forum Langage
    Réponses: 4
    Dernier message: 12/12/2005, 12h24
  5. Structure de données de type "RECORD"
    Par chaours dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/09/2002, 17h10

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