= Alexandre le Grand =
email : alexandre.le.grand@libertysurf.f
I Introduction Bonjour nous allons aujourd'hui aborder l'utilisation des flux en programmationDelphi. 1) Qu'est qu'un flux : Un flux c'est une suite de données continues. Cette suite peut se trouver sur un disque (fichier), en mémoire, sur une connexion... 2) Particularités d'un flux - Un flux possède une méthode d'écriture et de lecture. - L'unité de lecture et d'écriture est l'octet. - Le déplacement dans un flux se fait grâce à un pointeur. Plusieurs méthodes permettent ce déplacement. 3) Avantage des flux. - La rapidité de traitement. - C'est un moyen "universel" de lire et d'écrire des données sur un support. 4) TStream et ses descendants TStream est la classe abstraite qui propose les méthodes de base pour la lecture et l'écriture dans un flux. Chaque descendant devra donc implémenter ces méthodes. TStream fournit donc l'architecture nécessaire à la gestion d'un flux. Plusieurs classes vont en héritées : - TFileStream (pour l'utilisation de fichiers) - TStringStream (pour la manipulation de chaînes en mémoire) - TMemoryStream (pour l'utilisation d'un tampon mémoire) - TBlobStream (pour l'utilisation de champs BLOB) - TWinSocketStream (pour la lecture et l'écriture sur une connexion socket) - TOleStream (pour l'utilisation d'une interface COM en lecture et écriture) II Programme exemple Nous allons pour cette première partie utiliser les méthodes de base d'écriture et de lecture en utilisant TMemoryStream. L'exemple nous permettra de créer entièrement une petite base de données sans faire appel à BDE. Le principe : 1) créer un objet de type TMemoryStream (SMemory) qui servira de tampon pour stocker les enregistrements. La mise à jour se fait en sauvegardant le contenu de SMemory dans le fichier "contact". 2) Chaque enregistrement est de taille fixe et contient les différents champs.} Nous allons donc pour comprendre comment fonctionne un flux reprendre une partie du code source du sample téléchargeable sur mon site : http://herea.soft.free.fr Les routines ici exposées seront celles qui permettent la navigation dans notre base de données ainsi que l'ajout et la suppression d'un enregistrement. Vous pourrez suivre le fil du code grâce aux commentaires largement insérés. III Partie code source Unit Unit1; Interface Uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls, ActnList, ToolWin, Mask, ImgList, ShellApi, ExtDlgs; Type TDirection = (dNext, dPrev, dBegining, dEnd); // Ici déclaration d'un objet record regroupant les champs de notre // base de données. TInfos = Record Name : Array[0..50] Of char; FirstName : Array[0..50] Of char; Tel : Array[0..14] Of char; Fax : Array[0..14] Of char; Relation : Bool; email : Array[0..60] Of char; Address : Array[0..255] Of Char; PostCode : Integer; End; TForm1 = Class(TForm) checkPrivate : TRadioButton; CheckBusiness : TRadioButton; Editemail : TEdit; MemoAddress : TMemo; MaskFax : TMaskEdit; MaskTel : TMaskEdit; EditFirstName : TEdit; EditName : TEdit; MaskPostCode : TMaskEdit; LabelCount : TLabel; ....... Public Procedure ReadRecord(Direction : TDirection); Procedure WriteRecord; Procedure UpdateRecord; Procedure DelRecord; Procedure ClearFields; { Déclarations publiques } End; Const // Nom du fichier FilePath = 'Contacts'; Var Form1 : TForm1; // Tampon SMemory : TMemoryStream; Implementation {$R *.DFM} // Lecture / écriture / ajout / suppression------------------------------------- Procedure TForm1.ReadRecord(Direction : TDirection); // Lecture d'un enregistrement. Direction indique // quel enregistrement lire par rapport à la position // courante : dNext > le suivant, dPrev > le précédent, // dBegining > le premier, dEnd > le dernier. Var Infos : TInfos; Begin ZeroMemory(@Infos, SizeOf(TInfos)); If SMemory.Size <> 0 Then Begin Case Direction Of dNext : Begin // On vérifie si l'on n'est pas au dernier enregistrement If SMemory.Position = SMemory.Size - SizeOf(TInfos) Then exit; // On avance d'un enregistrement SMemory.Position := SMemory.Position + SizeOf(TInfos); End; dPrev : Begin // On vérifie si l'on n'est pas au premier enregistrement If SMemory.Position = 0 Then exit; // On recule d'un enregistrement SMemory.Position := SMemory.Position - SizeOf(TInfos); End; // On se place au début dBegining : SMemory.Seek(0, soFromBeginning); // On se place à la fin dEnd : SMemory.Seek(-SizeOf(TInfos), soFromend); End; // On lit l'enregistrement SMemory.Read(Infos, SizeOf(TInfos)); // On se repositionne au début de l'enregistrement lu SMemory.Position := SMemory.Position - SizeOf(TInfos); // On remplit les champs LabelCount.Caption := 'Position : ' + IntToStr(SMemory.Position Div SizeOf(TInfos) + 1) + ' / ' + IntToStr(SMemory.Size Div SizeOf(TInfos)); EditName.Text := Infos.Name; EditFirstName.Text := Infos.FirstName; MaskTel.Text := Infos.Tel; MaskFax.Text := Infos.Fax; Editemail.Text := Infos.email; MemoAddress.Text := Infos.Address; If Infos.Relation Then CheckPrivate.Checked := true Else CheckBusiness.Checked := True; MaskPostCode.Text := IntToStr(Infos.PostCode); End; End; //------------------------------------------------------------------------------ Procedure TForm1.WriteRecord; // Ecriture d'un enregistrement Var Infos : TInfos; Begin // On initialise Infos ZeroMemory(@Infos, SizeOf(TInfos)); // On récupère les différentes valeurs des champs Strcopy(Infos.Name, PChar(EditName.Text)); Strcopy(Infos.FirstName, PChar(EditFirstName.Text)); Strcopy(Infos.Tel, PChar(MaskTel.Text)); Strcopy(Infos.Fax, PChar(MaskFax.Text)); Strcopy(Infos.email, PChar(Editemail.Text)); Strcopy(Infos.Address, PChar(MemoAddress.Text)); Infos.Relation := CheckPrivate.Checked; Infos.PostCode := StrToInt(MaskPostCode.Text); // On écrit la structure Infos à la position courante du tampon SMemory SMemory.Write(Infos, SizeOf(TInfos)); // On se repositionne au début de l'enregistrement écrit SMemory.Position := SMemory.Position - SizeOf(TInfos); LabelCount.Caption := 'Position : ' + IntToStr(SMemory.Position Div SizeOf(TInfos) + 1) + ' / ' + IntToStr(SMemory.Size Div SizeOf(TInfos)); End; //------------------------------------------------------------------------------ Procedure TForm1.UpdateRecord; // Mise à jour Begin WriteRecord; SMemory.SaveToFile(FilePath); End; //------------------------------------------------------------------------------ Procedure TForm1.DelRecord; // Effacement d'un enregistrement Var CurrentPos : Integer; TempMemory : TMemoryStream; Begin If SMemory.Size <> 0 Then Begin CurrentPos := SMemory.Position; TempMemory := TMemoryStream.Create; Try //On copie du début jusqu'à l'enregistrement à supprimer SMemory.Position := 0; If CurrentPos <> 0 Then TempMemory.CopyFrom(SMemory, CurrentPos); // On saute l'enregistrement à supprimer SMemory.Position := SMemory.Position + SizeOf(TInfos); // On copie jusqu'à la fin If SMemory.Position <> SMemory.Size Then TempMemory.CopyFrom(SMemory, SMemory.Size - SMemory.Position); SMemory.Clear; SMemory.LoadFromStream(TempMemory); SMemory.Position := CurrentPos; ClearFields; // On se positionne soit sur l'enregistrement précédent soit sur le premier If SMemory.Position = SMemory.Size Then ReadRecord(dEnd) Else ReadRecord(dNext); // On sauvegarde SMemory.SaveToFile(FilePath); Finally TempMemory.Free; End; End; End; //------------------------------------------------------------------------------ Procedure TForm1.ClearFields; // Vidage des champs Begin EditName.Text := ''; EditFirstName.Text := ''; MaskTel.Text := ''; MaskFax.Text := ''; Editemail.Text := ''; MemoAddress.Text := ''; CheckPrivate.Checked := True; MaskPostCode.Text := '00000'; End; //Commande de déplacement dans SMemory------------------------------------------ Procedure TForm1.BeginingExecute(Sender : TObject); // Pour la commande appelle le premier enregistrement Begin ReadRecord(dBegining); End; //------------------------------------------------------------------------------ Procedure TForm1.PreviousExecute(Sender : TObject); // Pour la commande appelle l'enregistrement précédent Begin ReadRecord(dPrev); End; //------------------------------------------------------------------------------ Procedure TForm1.NextExecute(Sender : TObject); // Pour la commande appelle l'enregistrement suivant Begin ReadRecord(dNext); End; //------------------------------------------------------------------------------ Procedure TForm1.TheEndExecute(Sender : TObject); // Pour la commande appelle le dernier enregistrement Begin ReadRecord(dEnd); End; //------------------------------------------------------------------------------ Procedure TForm1.UpdateExecute(Sender : TObject); // Pour la commande de mise à jour de l'enregistrement courant Begin UpdateRecord; End; //------------------------------------------------------------------------------ Procedure TForm1.AddExecute(Sender : TObject); // Pour la commande d'ajout d'un enregistrement Begin // On se place à la fin SMemory.Seek(0, soFromend); // On vide les champs ClearFields; End; //------------------------------------------------------------------------------ Procedure TForm1.SupprExecute(Sender : TObject); // Pour la commande de suppression d'un enregistrement Begin DelRecord; End; //Voilà si vous avez des questions : alexandre.le.grand@libertysurf.fr = Alexandre le Grand =
|