2010-05-25 15 views
2

Je dois stocker plusieurs objets (la plupart d'entre eux sont TObject/non persistant) dans un TMemoryStream, enregistrer le flux sur le disque et le charger à nouveau. Les objets doivent être diffusés les uns après les autres. Une sorte de conteneur universel.Diffusion de plusieurs TObjects vers un TMemoryStream

Au moment où je mets toutes les propriétés/champs/variables d'un objet dans un enregistrement et enregistrer l'enregistrement à diffuser. Mais j'ai l'intention d'utiliser le fichier de fonctions WriteInterger, WriteString (voir ci-dessous), WriteBoolean, etc fonctions pour enregistrer/charger des données à partir du flux.

StreamReadString(CONST MemStream: TMemoryStream): string; 
StreamWriteString(CONST MemStream: TMemoryStream; s: string); 

Cependant, il semble que j'ai besoin de réécrire beaucoup de code. Un des nombreux exemples est TStringList.LoadFromStream qui ne fonctionnera pas, il doit donc être réécrit. C'est parce que TStringList doit être le dernier objet dans le flux (il lit à partir de la position actuelle à la fin du flux).

Quelqu'un connaît une bibliothèque qui fournit des fonctionnalités de base comme celle-ci? J'utilise Delphi 7 pour que RTTI ne soit pas génial.

Répondre

1

Voir poste lié here

BTW, Delphi7 supporte aussi RTTI, sinon vos formulaires (.dfm) ne peuvent pas être chargés :-)
Si vous utilisez les propriétés publiées, RTTI travaillera pour vous « sur la boîte".
Sinon, vous devez le faire vous-même avec un

procedure DefineProperties(Filer: TFiler); override;

Vous pouvez jeter un oeil à la façon dont il est mis en œuvre:

procedure TDataModule.DefineProperties(Filer: TFiler); 

Ce sont les seuls moyens de sérialisation d'objets.
Mais vous pouvez aussi essayer des enregistrements: si vous n'utilisez pas array (les chaînes sont aussi des tableaux de char) ou des propriétés d'objet, vous pouvez directement enregistrer et charger un enregistrement en mémoire (stream, fichier, etc). Je l'utilise dans mon AsmProfiler pour pouvoir lire et écrire de nombreux (petits) résultats très rapidement (un tableau d'enregistrements avec des valeurs entières peut être enregistré et chargé avec un appel Move/CopyMemory!).

+0

Pour l'instant, je mets toutes les propriétés/champs/variables d'un objet dans un enregistrement et enregistrer l'enregistrement à diffuser. Mais j'ai l'intention d'utiliser mes fonctions 'WriteInterger', 'WriteString', 'WriteBoolean', etc. pour sauvegarder/charger des données depuis un flux. – Ampere

1

Quelle version de Delphi? Delphi 2010 a une nouvelle fonctionnalité RTTI, donc vous pouvez utiliser DeHL qui a "sérialisation générique complète pour tous les types et collections inclus". Pourquoi ne pas utiliser XML?

+0

Désolé. J'ai oublié d'ajouter: Delphi 7. – Ampere

+1

Ok, alors vous pouvez essayer "http://opensource.hitsoft-it.com/display/HitXMLe/General+Description" (nous utilisons cela dans D2007 pour la sérialisation en xml) –

1

  1. Écrivez un XSD pour le XML qui définit le XML.
  2. Génère un formulaire d'unité Delphi XSD à l'aide de l'Assistant Liaison de données XML.
  3. Placez un tas de vos objets dans ce fichier XML.
  4. Enregistrez le fichier XML sur le disque (ou diffusez-le sur un autre support).

Pour plus d'informations sur XML et l'Assistant Liaison de données XML, voir this answer.

Edit:

qu'élaborer vos objets aux interfaces/objets générés à partir du XSD; ou utilisez les objets/interfaces qui ont été générés. Cela est généralement beaucoup plus facile que d'accrocher dans le mécanisme de streaming Delphi (soit en écrivant des wrapper TPersistent avec des propriétés publiées autour de vos objets, en allant de manière DefineBinaryProperty, soit de manière TReader/TWriter/DefineProperty).

--jeroen

+0

Will this XML fonctionne avec des propriétés non publiées et des classes non persistantes telles que TObject? Je suis également préoccupé par la taille du fichier généré qui peut être plusieurs fois plus grand qu'un fichier binaire. – Ampere

+0

Wow: Quelqu'un déteste sûrement XML et downvoted moi :-) –

1

Avez-vous pensé à utiliser TReader et TWriter pour remplir vos flux.