I. Introduction▲
Qu'est-ce qu'un fichier ? C'est une partie de votre disque dur où sont stockées des informations à perpétuité (bon, après plusieurs années, ça peut commencer à devenir illisible…), à la différence de la mémoire RAM, qui est effacée constamment et qui perd toutes les données à chaque extinction de votre ordinateur.
Pour charger tous les exemples : ManiFich.zip.
II. Ouvrir un fichier▲
const
NomFich = 'test.pas'
;
var
F: File
;
begin
Assign (F, NomFich); FileMode := 0
; Reset (F,1
);
Close (F);
end
.
Voilà le code de base pour ouvrir un fichier.
Explications :
- « File » : type fichier dans lequel est stocké le nom du fichier, la position du curseur de lecture/écriture, etc. Mais ces dernières ne sont pas accessibles directement (ce n'est pas un problème, allons-nous voir plus loin) ;
- « Assign (F, NomFich); » : procédure qui stocke le nom du fichier (variable string NomFich) dans une variable de type File ou Text(type abordé plus loin) ;
- « FileMode := 0; » : le fichier sera ouvert dans le mode lecture seule (0). Autres modes : 1 = écriture seule, 2 = Lecture et écriture ;
- « Reset (F,1); » : ouvre le fichier dans le mode binaire (1 = longueur d'un enregistrement = mode octet/octet) ;
- « Close (F) » : ferme le fichier.
III. Les erreurs▲
Si le fichier « test.pas » n'existe pas dans le répertoire courant, Turbo Pascal va s'arrêter avec un message d'erreur du genre : « Error 2: File Not Found », et le programme se bloquera en affichant le message suivant : « Runtime error 002 at adress … : … », ce qui n'est pas génial.
Pour intercepter les erreurs, il faut ajouter la directive « {$I-} » avant « Assign (F, NomFich); » et rajouter « {$I+} » après « Reset (F,1); ». La directive « {$I-} » interrompt la détection d'erreur d'entrée/sortie par Turbo Pascal, et « {$I+} » la réactive.
Il faudra ensuite lire le code d'erreur après « {$I+} », qui est donné par IOResult. Si cette variable est nulle, aucune erreur ne s'est produite ; sinon, elle contient un code d'erreur. Pour décoder ce code, utilisez mon utilitaire Liste en tapant le message d'erreur dans la liste « Runtime error ».
Les plus courantes :
- 2 - Fichier introuvable ;
- 4 - Répertoire introuvable ;
- 5 - Fichier protégé en écriture (attribut lecture seule ou disquette protégée contre l'écriture).
IV. Créer un fichier binaire, puis y lire et écrire des données▲
const
NomFich = 'essai.bin'
;
var
F: File
; Erreur: Byte
;
a: Byte
; b: Array
[1
..10
] of
char
;
i: byte
;
begin
{ Initialise les données }
for
i := 1
to
10
do
b := ord('A'
) +i;
a := 123
;
{ Crée le fichier binaire, puis l'ouvre en mode lecture et écriture }
{$I-}
Assign (F, NomFich); FileMode := 2
; Rewrite (F); Reset (F,1
); {$I+}
Erreur := IOResult;
{ Teste les erreurs de création du fichier }
if
Erreur<>0
then
begin
Writeln ('Création du fichier impossible'
);
Writeln ('Erreur n°'
,erreur);
Halt (Erreur);
end
;
{ Ecrit un octet }
BlockWrite (F, a, 1
);
{ Ecrit 10 caractères }
BlockWrite (F, b, 10
);
{ Réouvre le fichier, ce qui permet de retourner au début du fichier }
Reset (F, 1
);
{ Lit un octet puis l'affiche }
BlockRead (F, a, 1
);
WriteLn ('a = '
,a);
{ Lit dix caractères puis les affiche }
BlockRead (F, b, 10
);
for
i := 1
to
10
do
WriteLn ('b['
,i,'] = '
,b[i]);
{ Ferme le fichier }
Close (F);
end
.
Voyons un peu les nouveaux éléments :
- « Rewrite (F); »: crée un nouveau fichier ;
- « IOResult »: vu plus haut, c'est le code d'erreur d'ouverture du fichier ;
- « BlockWrite (F, a, 1); »: écrit un nombre (de type word) d'octets (de n'importe quel type) dans le fichier F (de type File) à la position actuelle ;
- « BlockRead (F, a, 1); »: lit un nombre (de type word) d'octets dans le fichier F (de type File) à la position actuelle et les stocke dans a (de n'importe quel type) ;
- on voit que « Reset (F, 1); » peut être appelé une nouvelle fois pour rouvrir le fichier et donc placer le curseur de lecture (et écriture) au début du fichier.
V. Créer un fichier texte, y lire et écrire des lignes de texte, puis l'effacer▲
const
NomFich = 'essai.txt'
;
var
F: Text; Erreur: Byte
;
a: char
;
txt: String
;
begin
{ Initialise les données }
a := 'Z'
;
txt := 'Salut toi ! Ca va ?'
;
{ Crée le fichier texte, puis l'ouvre en mode lecture et écriture }
{$I-}
Assign (F, NomFich); FileMode := 2
; Rewrite (F); Reset (F); {$I+}
Erreur := IOResult;
{ Teste les erreurs de création du fichier }
if
Erreur<>0
then
begin
Writeln ('Création du fichier impossible'
);
Writeln ('Erreur n°'
,erreur);
Halt (Erreur);
end
;
{ Ecrit un caractère }
Write
(A, txt);
{ Ecrit une ligne }
Writeln (F, txt);
{ Réouvre le fichier ce qui permet de retourner au début du fichier }
Reset (F);
{ Lit un caractère puis l'affiche }
Read
(F, a);
WriteLn ('A = '
,a);
{ Lit une ligne puis l'affiche }
ReadLn (F, txt);
WriteLn (txt);
{ Ferme le fichier }
Close (F);
{ Efface le fichier }
Erase (F);
end
.
Nous remarquons que le code source n'a que peu changé. Voilà ce qui change :
- la variable « F » est maintenant de type Text ;
- lors de l'ouverture, on utilise « Reset (F); » et non plus « Reset (F,1); » ;
- on écrit grâce au classique « Write[Ln] », sauf qu'il faut à chaque fois préciser la variable fichier au début de la parenthèse ;
- on lit grâce au classique « Read[Ln] », sauf qu'il faut à chaque fois préciser la variable fichier au début de la parenthèse ;
- pour effacer le fichier, il suffit de le fermer puis d'appeler « Erase (F); ».
VI. Fonctions complémentaires pour les fichiers accédés en mode binaire▲
Attention, ces fonctions ne fonctionnent que pour les fichiers ouverts en mode binaire (« Reset (F,1) ») !
const
NomFich = 'essai.bin'
;
var
F: File
; Erreur: Byte
; a: Byte
;
begin
{ Ouvre un fichier en mode binaire et lecture seule }
{$I-}
Assign (F, NomFich); FileMode := 0
; Reset (F,1
); {$I+}
Erreur := IOResult;
{ Teste les erreurs d'ouverture du fichier }
if
Erreur <> 0
then
begin
Writeln ('Fichier introuvable'
);
Writeln ('Erreur n°'
,erreur);
Halt (Erreur);
end
;
{ Affiche la taille du fichier }
Writeln ('Le fichier fait '
, FileSize(F), ' octets'
);
{ Se positionne au milieu du fichier }
Seek (F, FileSize(F) div
2
);
{ Lit un octet puis l'affiche }
BlockWrite (F, b, 10
);
{ Réouvre le fichier, ce qui permet de retourner au début du fichier }
Reset (F, 1
);
{ Lit un octet puis l'affiche }
BlockRead (F, a, 1
);
WriteLn ('a = '
,a);
{ Ferme le fichier }
Close (F);
end
.
Les nouvelles procédures sont :
- « FileSize(F) » : fonction donnant la taille en octets d'un fichier ;
- « Seek (F, FileSize(F) div 2 ); » : positionne le curseur d'écriture/lecture d'un fichier.
VII. Remerciements▲
Merci à Damien Genthial pour ses corrections.