Sign in Join
Wiki copytemporary

File Handling In Pascal/fr: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: File Handling In Pascal/fr

OldNewLine
1+Une chose que doit savoir faire un développeur est de travailler avec des fichiers. Les fichiers servent à garder les réglages utilisateur, les rapports d'erreur et plus encore. Ici, je vais vous apprendre comme travailler avec des simples fichiers texte.
2+
3+# Vieux style porocédural
4+
5+Lorsque vous utilisez des fichiers en Pascal classique (non orienté objet), vous pouvez utiliser un type TextFile qui vous permet d'écrire de la chaîne dans le fichier ou créer votre propre type de fichier.
6+
7+``` pascal
8+...
9+type
10+ TIntegerFile = file of Integer; // Vous permet d'écrire des entiers dans le fichier
11+ TPCharFile = file of PChar; // Ecrire des PChars dans le fichier :\
12+ TStringFile = file of String; // Ecrire des chaînes dans le fichier
13+...
14+```
15+
16+Si nous faisons uniquement TStringFile = File, alors il serait impossible d'écrire quelque chose dedans! Aussi, vous ne pouvez pas écrire des entiers directement dans TStringFile parce que c'est un fichier de chaînes.
17+
18+## IO
19+
20+IO est le truc de la gestion des fichiers pour Pascal. Il dit au compilateur comment traiter les situations d'erreurs d'E/S: lever une exception ou stocker le code d'erreur dans la variable IOResult. Puisqu'il s'agit d'une directive de compilation, vous devez faire ceci:
21+
22+``` pascal
23+{$I-} // Désactive le contrôle. De cette façon, toutes les erreurs vont dans la variable IOResult
24+{$I+} // Remets le contrôle; les erreurs vont mener à une exception EInOutError.
25+```
26+
27+En désactivant/éteignant \$I, les résultats des opérations de fichier vont dans la variable IOResult. C'est un [[Cardinal|type cardinal (nombre)]]. Si vous voulez écrire l'erreur, vous utilisez la fonction IntToStr. Différents nombres signifie différentes erreurs. Aussi, vous pouvez vouloir vérifier la documentation pour les différentes erreurs: [1](http://www.freepascal.org/docs-html/rtl/system/ioresult.html).
28+
29+## Procédures pour les fichiers
30+
31+Ces procédures et fonctions de manipulation de fichiers sont placées dans l'unité system, elles sont donc toujours disponibles sans avoir à déclarer cette unité dans votre programme. Voir la documentation de FPC pour plus de détails: [Reference for 'System' unit](http://www.freepascal.org/docs-html/rtl/system/index-5.html)
32+
33+- **Assign** - Affecte un nom au fichier
34+- **Append** - Ouvre un fichier existant pour ajouter des données à la fin et l'éditer
35+- **BlockRead** - Lit les données d'un fichier non typé dans la mémoire
36+- **BlockWrite** - Ecrit des données de la mémoire vers un fichier non typé
37+- **Close** - Ferme un fichier ouvert
38+- **EOF** - Vérifie si la fin du fichier est atteinte
39+- **Erase** - Efface un fichier du disque
40+- **FilePos** - Retourne la position courante dans un fichier
41+- **FileSize** - Retourne la taille du fichier
42+- **Flush** - Ecrit les tampons de fichier sur le disque
43+- **IOResult** - Retourne le résultat de la dernière opération d'E/S fichier
44+- **Read** - Lit dans une variable depuis un fichier
45+- **ReadLn** - Lit dans une variable depuis un fichier et va à la prochaine ligne
46+- **Reset** - Ouvre un fichier en lecture
47+- **Rewrite** - Ouvre un fichier en écriture
48+- **Seek** - Change la position courante dans le fichier
49+- **SeekEOF** - Met la position courante en fin de fichier
50+- **SeekEOLn** - SMet la position courante en fin de ligne
51+- **Truncate** - Tronque le fichier à la position courante
52+- **Write** - Ecrit la variable dans un fichier texte
53+- **WriteLn** - Ecrit la variable dans un fichier texte et ajoute une nouvelle ligne (vide)
54+
55+## Exemple
56+
57+Un exemple complet de manipulation de fichier texte:
58+
59+``` pascal
60+program FileTest;
61+
62+{$mode objfpc} // Ne m'oublier jamais
63+
64+uses
65+ Sysutils;
66+
67+var
68+ FileVar: TextFile;
69+
70+begin
71+ WriteLn('Test de fichier');
72+ AssignFile(FileVar, 'Test.txt'); // Vous n'avez pas à mettre. Txt, mais c'est juste pour l'instant
73+ {$I+} //Utilise les exceptions
74+ try
75+ Rewrite(FileVar); // Créer le fichier
76+ Writeln(FileVar,'Salut');
77+ CloseFile(FileVar);
78+ except
79+ on E: EInOutError do
80+ begin
81+ Writeln('Une erreur de manipulation de fichier s''est produite. Détails: '+E.ClassName+'/'+E.Message);
82+ end;
83+ end;
84+ WriteLn('Programme terminé. Pressez Entrée pour arrêter.');
85+ ReadLn;
86+end.
87+```
88+
89+Maintenant ouvrez le fichier avec un éditeur de texte (Bloc-note...), vous verrez écrit Salut dedans! Vous pouvez tester la gestion des erreurs en mettant test.txt en lecture seule et en rejouant le programme.
90+
91+Remarquez que nous avons utilisé la gestion des exceptions ({\$I+}) car c'est plus facile pour réaliser de multiples opérations de fichiers et pour gérer les erreurs. Vous pouvez aussi utiliser {\$I-}, mais vous aurez à vérifier IOResult après chaque opération et modifier votre prochaine opération.
92+
93+Voici comment l'ajout en fin/ajout dans un fichier fonctionne:
94+
95+``` pascal
96+program EditFile;
97+
98+{$mode objfpc}
99+
100+uses
101+ Sysutils;
102+
103+var
104+ File1: TextFile;
105+
106+begin
107+ WriteLn('Ajout en fin de fichier');
108+ {$I+}
109+ try
110+ AssignFile(File1, 'File.txt');
111+ Append(File1, 'Ajouter du texte...');
112+ CloseFile(File1);
113+ except
114+ on E: EInOutError do
115+ begin
116+ Writeln('Une erreur de gestion de fichier s''est produite. Détails: '+E.ClassName+'/'+E.Message);
117+ end;
118+ end;
119+ WriteLn('Programme terminé. Pressez Entrée pour arrêter.');
120+ ReadLn;
121+end.
122+```
123+
124+Lecture d'un fichier:
125+
126+``` pascal
127+program ReadFile;
128+
129+{$mode objfpc}
130+
131+uses
132+ Sysutils;
133+
134+var
135+ File1: TextFile;
136+ Str: String;
137+
138+begin
139+ Writeln('Lecture de fichier:');
140+ AssignFile(File1, 'File.txt');
141+ {$I+}
142+ try
143+ Reset(File1);
144+ repeat
145+ Readln(File1, Str); // Lit la ligne entière depuis le fichier
146+ Writeln(Str); // Ecrit la ligne lue à l'écran
147+ until(EOF(File1)); // EOF(Fin de fichier) le programme continue à lire des nouvelles jusqu'à la fin
148+ CloseFile(File1);
149+ except
150+ on E: EInOutError do
151+ begin
152+ Writeln('File handling error occurred. Details: '+E.ClassName+'/'+E.Message);
153+ end;
154+ end;
155+ WriteLn('Programme terminé. Pressez Entrée pour arrêter.');
156+ ReadLn;
157+end.
158+```
159+
160+Il est possible de faire un peu de manipulation de fichiers en utilisant les caractères au lieu de chaînes. Cela rend l'air cool: D.
161+
162+# Style objet
163+
164+En plus des routines de manipulation de fichier vieux style mentionnées ci-dessus, un nouveau système existe qui utilise le concept des flux (flux de donnée) à un niveau d'abstraction plus élevé, ce qui veut dire que vous en tant que programmeur avez moins de chose à faire pour traiter les fichiers.
165+
166+En plus, la plupart des classes de manipulation de chaînes ont la capacité de charger ou sauver du contenu depuis/vers un fichier. Ces méthodes sont appelées généralement LoadFromFile et SaveToFile. Beaucoup d'autres objets (tels les grilles de Lazarus) ont des fonctionnalités similaires, comprenant les ensembles de données (DBExport); cela vaut le coup de regarder la documentation du code source avant d'essayer de faire vos propres routines.
167+
168+## Fichiers binaires
169+
170+Pour l'ouverture des fichiers en accès direct, TFileStream devrait être utilisé. Cette classe est une encapsulation des procédures FileOpen, FileCreate, FileRead, FileWrite, FileSeek et FileClose qui se trouvent dans l'unité FileUtil.
171+
172+[IO routines](http://www.freepascal.org/docs-html/rtl/sysutils/ioroutines.html)
173+
174+Dans l'exemple du dessous; remarquez comment nous encadrons l'action de manipulation de fichier avec un bloc try..finally. Cela assure que le l'objet TFileStream est toujours libéré (la partie finally...) même s'il y a une erreur d'accès au fichier (ou autre).
175+
176+``` pascal
177+var
178+ Buffer: array[0..9999] of Byte;
179+begin
180+ with TFileStream.Create('SomeFile.bin', fmCreate) do
181+ try
182+ Seek('Salut');
183+ Write(Buffer, SizeOf(Buffer));
184+ finally
185+ Free;
186+ end;
187+end;
188+```
189+
190+Vous pouvez charger les fichiers entiers dans la mémoire s'ils sont comparativement plus petits que la mémoire système. De plus grosses tailles pourraient marcher mais le système d'exploitation commencera à utiliser la mémoire virtuelle (swap), rendant l'exercice inutile du point de vue des performances.
191+
192+``` pascal
193+begin
194+ with TMemoryStream.Create do
195+ try
196+ LoadFromFile('SomeFile.bin');
197+ Seek(0, soEnd);
198+ Write(Ord('A'), 1);
199+ SaveToFile('SomeFile.bin');
200+ finally
201+ Free;
202+ end;
203+end;
204+```
205+
206+Avec des fichiers de plusieurs Go, vous voudriez lire dans des tampons de, disons, 4096 octets (il est conseillé de choisir un multiple du secteur du système de fichier ou de la taille de bloc) et faire quelque chose avec les données de chaque tampon lu.
207+
208+``` pascal
209+var
210+ TotalBytesRead, BytesRead : Int64;
211+ Buffer : array [0..4095] of byte; // ou, array [0..4095] of char
212+ FileStream : TFileStream;
213+
214+try
215+ FileStream := TFileStream.Create;
216+ FileStream.Position := 0; // Garantir que vous êtes en début de fichier
217+ while TotalBytesRead <= FileStream.Size do // Tant que la qté de donnée lue est <= la taille du flux, faire
218+ begin
219+ BytesRead := FileStream.Read(Buffer,sizeof(Buffer)); // Lire 4096 octet de donnée
220+ inc(TotalBytesRead, BytesRead); // Ajouter BytesRead à TotalByteRead, i.e. 4096 octets
221+ // Faire qque chose avec les données
222+ end;
223+```
224+
225+### FileCopy
226+
227+Avec ce qui précède, nous pouvons implémenter une simple fonction de copie de fichier (FreePascal n' pas une telle fonction dans sa RTL, bien que Lazarus en a), ajuster comme il se doit pour les gros fichiers
228+
229+``` pascal
230+function FileCopy(Source, Target: string): boolean;
231+// Copie la source dans la cible (target); écrase la cible d'avant.
232+// Copie le fichier entier en mémoire.
233+// Retourne true en cas de succès; false sinon
234+var
235+ MemBuffer: TMemoryStream;
236+begin
237+ result:=false;
238+ MemBuffer:=TMemoryStream.Create;
239+ try
240+ try
241+ MemBuffer.LoadFromFile(Source);
242+ MemBuffer.Position:=0;
243+ MemBuffer.SaveToFile(Target); //peut être le même que la source
244+ result:=true;
245+ except
246+ result:=false; //avale l'exception, convertit en code d'erreur
247+ end;
248+ finally
249+ MemBuffer.Free;
250+ end;
251+end;
252+```
253+
254+## Fichiers Texte
255+
256+En général, pour les fichiers texte, vous pouvez utiliser la classe TStringList pour charger le fichier entier en mémoire et avoir un accès simple à ses lignes. Bien sûr, vous pouvez aussi sauver la StringList dans le fichier:
257+
258+``` pascal
259+begin
260+ with TStringList.Create do
261+ try
262+ Add('Salut');
263+ SaveToFile('SomeFile.txt');
264+ finally
265+ Free;
266+ end;
267+end;
268+```
269+
270+Pour écrire une simple ligne dans un flux, vous pourriez utiliser la procédure suivante:
271+
272+``` pascal
273+procedure SaveStringToPath(theString, filePath: String);
274+var
275+ textFile: TFileStream = nil;
276+ textLength: integer;
277+ stringBuffer: ^String;
278+begin
279+ textLength := length(theString);
280+ try
281+ textFile := TFileStream.Create(filePath, fmOpenWrite or fmCreate);
282+ { écrire la chaîne dans une flux tout en évitant d'écrire la longueur initiale }
283+ stringBuffer := @theString + 1;
284+ textFile.WriteBuffer(stringBuffer^, textLength);
285+ finally
286+ if textFile <> nil then textFile.Free;
287+ end;
288+end;
289+```
290+
291+## Voir aussi
292+
293+- [[File]]
294+
295+---
296+*From the Free Pascal wiki, page "File Handling In Pascal/fr", as it stood on 2020-02-14 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history