Developpez.com - Delphi
X

Choisissez d'abord la catégorieensuite la rubrique :



Un extrait de source pour comprendre les
flux en programmation DELPHI

= 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 =
ALG SITE : http://herea.soft.free.fr
email : alexandre.le.grand@libertysurf.f

Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -