novembre
2008
Dans mes deux billets précédents je montrais comment sauvegarder les objets dans des fichiers-textes. Le chargement des objets à partir des fichiers fait l’objet de ce sixième article.
2.1.3 – Lecture des fichiers-textes
Dans FormRepert il suffit de cloner la méthode SavePeopleToFile comme ci-dessous:
var
CsvRead: TCsvTextFileRead;
TxtRead: TFixedTextFileRead;
FileExt: String;
begin
FileExt := ExtractFileExt(FN) ;
if FileExt = '.csv' then begin
CsvRead := TCsvTextFileRead.Create(FN);
try
People.AcceptBizObjVisitor(CsvRead);
finally
CsvRead.Free;
end;
end else if FileExt = '.txt' then begin
TxtRead := TFixedTextFileRead.Create(FN);
try
People.AcceptBizObjVisitor(TxtRead);
finally
TxtRead.Free;
end;
end else
ShowMessage('Format de fichier incorrect (extension '+FileExt+')');
end;
Nous voyons qu’il nous faut construire deux nouveaux visiteurs : TCsvTextFileRead et TFixedTextFileRead.
Nous avons vu que les visiteurs d’écriture sauvegardent les données lors de leur destruction. Pour éviter que les visiteurs de lecture ne sauvegardent immédiatement les fichiers lus, il nous faudra donc modifier les destructeurs dans la hiérachie des classes de gestion des fichiers.
A part ça, la structure des visiteurs pour la lecture des fichiers est identique à celle des visiteurs d’écriture. Seul change le contenu de la méthode VisitBizObj.
2.1.3.1 – Fichiers .txt
Pour la lecture des fichiers .txt nous utiliserons le visiteur TFixedTextFileRead.
public
destructor Destroy; override;
procedure VisitBizObj(Visited: TBizObj); override;
end;
implementation
uses
uBOMRep;
{
****************************** TFixedTextFileRead ******************************
}
destructor TFixedTextFileRead.Destroy;
begin
inherited Destroy;
end;
procedure TFixedTextFileRead.VisitBizObj(Visited: TBizObj);
var
i: Integer;
s: string;
Person: TPerson;
begin
if not(Visited is TPeople) then
Exit;
FStringList.LoadFromFile(FFileName);
TPeople(Visited).Clear;
for i := 0 to FStringList.Count - 1 do begin
s := FStringList.Strings[i];
Person := TPerson.Create;
with Person do begin
LastName := Trim(copy(s,1,20));
FirstName := Trim(copy(s,21,20));
BirthDate := StrToDate(Trim(copy(s,41,10)));
end;
TPeople(Visited).Add(Person);
end;
end;
No comment !
2.1.3.2 – Fichiers .csv
Pour la lecture des fichiers .csv nous utiliserons le visiteur TCsvTextFileRead.
public
destructor Destroy; override;
procedure VisitBizObj(Visited: TBizObj); override;
end;
implementation
uses
uBOMRep;
{
******************************* TCsvTextFileRead *******************************
}
destructor TCsvTextFileRead.Destroy;
begin
inherited Destroy;
end;
procedure TCsvTextFileRead.VisitBizObj(Visited: TBizObj);
var
i: Integer;
s: string;
Person: TPerson;
function ExtractField(line: string; num: Integer): string;
var
s: string;
n: Integer;
p: Integer;
f: string;
begin
s := line;
n := 0;
repeat
p := pos(';',s);//position du séparateur ";"
if p = 0 then
f := s //il n'y a plus de séparateur, c'est le dernier champ
else begin
f := copy(s, 1, p - 1);//permier champ de la ligne (avant le séparateur ";"
s := copy(s, p + 1, length(s) - p);//ligne amputée de f et du premier séparateur
end;
inc(n);
until n >= num;
result := f;
end;
begin
if not(Visited is TPeople) then
Exit;
FStringList.LoadFromFile(FFileName);
TPeople(Visited).Clear;
for i := 0 to FStringList.Count - 1 do begin
s := FStringList.Strings[i];
Person := TPerson.Create;
with Person do begin
LastName := ExtractField(s,1);
FirstName := ExtractField(s,2);
BirthDate := StrToDate(ExtractField(s,3));
end;
TPeople(Visited).Add(Person);
end;
end;
La méthode VisitBizObj a la particularité de posséder une fonction locale pour extraire les champs LastName, FirstName et BirthDate de chaque ligne de la StringList. Il y a certainement des solutions plus élégantes. Mais ce n’est pas l’objectif de ce tutoriel. N’hésitez pas à apporter votre contribution. Je suis preneur de toute amélioration du code, à condition qu’il reste facilement compréhensible.
Nous pouvons maintenant nous attaquer plus sérieusement à l’interface-utilisateur.