Section courante

A propos

Section administrative du site

Les fichiers

Un micro-ordinateur n'entreposant pas les programmes et les données est un peu une calculatrice puissante. Les gens ayant acheté les premiers micro-ordinateurs sans unité de disque l'ont vite découvert : lorsqu'ils ont éteint leurs ordinateurs, leur travail a disparu. Bien sûr, votre ordinateur possède au moins un unité de disque de disquettes et éventuellement un unité de disque dur. Il vous permet de profiter des puissantes opérations de fichiers sur disque de Turbo Pascal. Apprendre à utiliser les fichiers disque est vital pour produire des programmes utiles, et Turbo Pascal aide en prenant en charge trois types de base de fichiers disque : texte, typé et non typé.

Concepts de gestion de fichiers

Tous les fichiers Turbo Pascal, quel que soit leur type, partagent des caractéristiques communes. Tout d'abord, tous les fichiers sont utilisés pour l'entrée ou la sortie. L'entrée est lorsqu'un programme prend des données d'un fichier et les utilise dans le programme; La sortie entrepose les résultats d'un programme dans un fichier ou envoie les résultats à un périphérique tel qu'un terminal ou une imprimante. Comme vous le verrez, il est également possible qu'un fichier soit utilisé à la fois pour l'entrée et la sortie.

Les fichiers peuvent être entreposés sur des disquettes et des unités de disque dur. Il existe bien sûr d'autres supports d'entreposage (bande magnétiques, disques optiques, disques RAM,...), mais ils sont moins courants. Le DOS exige que chaque fichier ait un nom de un à huit caractères. Les noms de fichiers peuvent également inclure une extension de trois lettres permettant généralement de décrire le contenu d'un fichier. Par exemple, le fichier programme Turbo Pascal est nommé TURBO.EXE. L'extension de nom de fichier .EXE indique au DOS qu'il s'agit d'un fichier programme pouvant être exécuté à partir du prompt DOS. Les fichiers source Turbo Pascal (les fichiers que vous créez avec l'éditeur Turbo Pascal) ont généralement l'extension de nom de fichier .PAS (par exemple, PROG1.PAS).

Si un fichier est entreposé dans le répertoire DOS, le répertoire fait également partie du nom de fichier. Si, par exemple, le fichier PROG1.PAS est le répertoire Turbo sur l'unité de disque C:, la description complète ou le chemin d'accès du nom de fichier est «C:\TURBO\PROG1.PAS».

Fichiers texte Turbo Pascal

Les fichiers texte se composent de lignes se terminant par un retour chariot et un saut de ligne (CR/LF) et contenant des caractères, des oeuvres et des phrases, comme le montre la figure suivantes :

Nom du fichier : TEST.DAT
Ligne 1 → C'est un exemple d'une ligne de texte.[CR/LF]
Ligne 2 → Chaque ligne dans un fichier texte se termine avec un[CR/LF]
Ligne 3 → retour de chariot et un saut de ligne.[CR/LF]
Ligne 4 → [CR/LF]
Ligne 5 → Même des lignes vides, comme celle ci-dessus.[CR/LF]
Ligne 6 → 49 12.34 0.12 70743 372324[CR/LF]

La combinaison CR/LF (codes ASCII 10 et 13) est appelée délimiteur. Un délimiteur marque la fin d'un élément, tel qu'un champ, un enregistrement ou, dans ce cas, la fin du fichier.

Vous pouvez savoir si un fichier est constitué de texte en utilisant la commande TYPE de DOS. Par exemple, vos disques Turbo Pascal sont livrés avec un fichier texte appelé README. Si vous entrez «TYPE README» à l'invite DOS et appuyez sur Enter, le fichier affiche un fichier non textuel (tel qu'un TURBO.EXE) de la même manière, vous ne verrez que du charabia.

Identificateurs de fichier texte

Avant de travailler avec des fichiers texte, vous devez déclarer un identificateur de fichier texte dans votre programme. Les identificateurs de fichier texte sont déclarés comme les identificateurs de variables, sauf que le type de données Turbo Pascal Text est utilisé. Voici un exemple de déclaration de fichier texte :

  1. Program TextFile;
  2. Var
  3.  TxtFile:Text;
  4.  
  5. BEGIN
  6. END.

Dans cette illustration, TxtFile est un identificateur de variable de type Text. Avant d'utiliser le fichier texte pour l'entrée ou la sortie, vous devez l'affecter à un fichier disque. Une instruction Assign typique ressemble à ceci :

  1. Assign(TxtFile,'TEXT.DAT');

Une fois que TxtFile est affecté à TEXT.DAT, le fichier disque n'est plus jamais référencé par son nom : toutes les opérations sur les fichiers se réfèrent à l'identifiant TxtFile.

Après avoir attribué un identificateur de fichier à un fichier disque, préparez le fichier disque avec l'une des trois commandes Turbo Pascal - Reset, Rewrite ou Append. La procédure Reset ouvre le fichier disque et le prépare en tant que fichier d'entrée. Seules les commandes d'entrée peuvent être utilisées sur un fichier ayant été réinitialisé. Toute tentative d'écriture dans un fichier texte Reset génère une erreur d'entrée/sortie.

La commande Reset positionne également le pointeur de fichier, un compteur gardant la trace de la position d'un programme dans un fichier, au début du fichier. Il fait que toutes les entrées démarrent au tout début du fichier et avancent à partir de là.

Une tentative de Reset sur un fichier n'existant pas généra une erreur d'entrée/sortie. Vous pouvez remplacer l'erreur d'entrée/sortie, si vous le souhaitez, en désactivant la directive du compilateur I avec l'instruction {$I-}.

Les procédures Rewrite et Append préparent tous deux un fichier texte pour la sortie, mais ils fonctionnent de différentes manières. Lorsqu'un fichier existant est préparé avec Rewrite, son contenu est effacé et le pointeur de fichier est placé au début du fichier. Si l'identificateur de fichier est attribué à un fichier inexistant, la commande Rewrite crée un fichier avec le nom donné dans l'instruction Assign. La commande Append, quant à elle, préserve le contenu d'un fichier et positionne le pointeur de fichier à la toute fin du fichier. Par conséquent, toutes les données ajoutées au fichier sont ajoutées à ce qui s'y trouve déjà.

Comme pour l'instruction Reset, si vous essayez d'utiliser Append sur un fichier n'existant pas, Turbo Pascal générera une erreur d'entrée/sortie.

Lorsque vous avez terminé d'utiliser un fichier pour l'entrée ou la sortie, vous devez fermer le fichier. La procédure Close exécute cette tâche et exécute plusieurs autres tâches dans le processus. La procédure Close s'assure que toutes les données des tampons temporaires sont entreposées sur le disque.

La commande Close libère également un descripteur de fichier DOS. Un descripteur de fichier (Handle) est un mécanisme fourni par DOS aux programmes aidant à gérer les opérations sur les fichiers. Lorsque vous utiliser les procédures Reset ou Rewrite sur un fichier, le DOS alloue un descripteur de fichier à Turbo Pascal. Étant donné que DOS limite le nombre de descripteurs de fichiers, vous ne pouvez pas ouvrir plus de 15 fichiers Turbo Pascal à la fois. La fermeture de fichiers permet de conserver une abondance de descripteurs de fichiers. Enfin, la commande Close met à jour le répertoire du fichier DOS pour refléter la taille, l'heure et la date du fichier.

Une fois fermé, un fichier ne peut pas être utilisé pour l'entrée ou la sortie tant qu'il n'est pas ouvert à nouveau avec Reset, Rewrite ou Append. Le lien entre l'identifiant du fichier et le fichier disque reste en vigueur même après la fermeture du fichier. Par conséquent, pour rouvrir un fichier, il n'est pas nécessaire de répéter la commande Assign. Ce processus est illustré avec le programme suivant :

  1. Program FileTime;
  2. Var
  3.  TxtFile:Text;
  4. BEGIN
  5.  Assign(TxtFile,'TEXT.DAT'); { Lie le fichier TxtFile au fichier TEXT.DATA }
  6.  Reset(TxtFile);             { Prépare TxtFile a être lu }
  7.  Rewrite(TxtFile);           { Prépare TxtFile à être réécrit }
  8.  Close(TxtFile);             { Ferme TxtFile, mise à jour du répertoire DOS }
  9.  Append(TxtFile);            { Réouvre le TxtFile pour la sortie additionnelle }
  10.  Close(TxtFile);             { La fermeture finale garantit que toute la sortie est enregistrée }
  11. END.

Lecture de chaînes de caractères à partir de fichiers texte

Une fois qu'un fichier texte est réinitialisé, vous pouvez en extraire des informations avec les procédures Read et ReadLn. Des exemples d'entrée de fichier texte peuvent être vus dans le programme suivant, dans lequel le fichier disque TEXT.DAT est lié à l'identificateur de fichier TxtFile.

  1. Program Text1;
  2. Var
  3.  TxtFile:Text;
  4.  S:String[80];
  5. BEGIN
  6.  Assign(TxtFile,'TEXT.DAT'); 
  7.  Reset(TxtFile);             
  8.  
  9.  ReadLn(TxtFile,S);
  10.  WriteLn(S);
  11.  
  12.  Read(TxtFile,S);
  13.  WriteLn(S);
  14.  Close(TxtFile);
  15. END. 

Par la suite, TxtFile est préparé pour la lecture avec la commande Reset. La première opération d'entrée est cet exemple de programme est l'instruction :

  1. ReadLn(TxtFile,s);

indiquant à Turbo Pascal de lire les caractères de la ligne courante du fichier et de les placer dans la variable chaîne de caractères s. Une fois les caractères lus, le pointeur de fichier ignore tous les caractères restants sur la ligne et se déplace au début de la ligne suivante dans le fichier.

Lors de la lecture d'une chaîne de caractères à partir d'un fichier texte avec la procédure ReadLn, trois situations possibles peuvent se produire :

Dans les deux premiers cas, Turbo Pascal lit tous les caractères laissés dans la ligne, les affecte à s, puis déplace le pointeur de fichier au début de la ligne suivante. La longueur de la chaîne de caractères est égale au nombre de caractères lus.

Dans le troisième cas, Turbo Pascal lit autant de caractères que nécessaire pour remplir la variable String, puis déplace le pointeur de fichier sur la ligne suivante. Tout caractère entre la fin de la chaîne de caractères et la fin de la ligne est ignoré.

La procédure Read fonctionne un peu comme la procédure ReadLn, mais après avoir été réadmis dans une chaîne de caractères, Read place le pointeur de fichier juste après le dernier caractère lu : il ne déplace pas le pointeur de fichier au début de la ligne suivante. Si la procédure Read rencontre un CR/LF (ou juste un simple retour chariot), indiquant que la fin de la ligne a été atteinte, elle arrête la lecture des caractères et ne fait pas avancer le pointeur de fichier tant qu'une procédure ReadLn n'est pas utilisée.

Lecture de plusieurs chaînes de caractères par ligne

Une seule procédure ReadLn peut lire plusieurs chaînes de caractères à la fois. Par exemple, l'instruction :

  1. ReadLn(TxtFile,s1,s2,s3);

lit les caractères de la ligne courante et remplit les variables s1, s2 et s3 de types de données String dans l'ordre. Si la ligne lue est :

Voici est un texte de caracteres

et les variables String sont toutes de type String[6], la String se verrait attribuer des valeurs comme suit :

Lecture de nombres à partir de fichiers texte

Les fichiers texte peuvent entreposer non seulement des mots et des phrases, mais également des données numériques. Les nombres, cependant, ne sont pas entreposés sous leur forme binaire mais sous forme de caractères. Par exemple, dans la RAM, la valeur Integer 20 545 est entreposée sous forme de deux octets sous forme de deux octets avec une valeur binaire de 0101000001000001. Mais dans un fichier texte, le nombre est entreposé sous forme de caractères 2, 0, 5, 4, 5, nécessitant un total de cinq octets. Lors de la lecture du nombre 20 545 à partir d'un fichier texte, le Turbo Pascal traduit le nombre d'une chaîne de caractères au format entier binaire.

Lorsqu'il lit un nombre à partir d'un fichier texte, le Turbo Pascal saute les caractères vides dans une ligne jusqu'à ce qu'il trouve un caractère non vide. Il lit ensuite les caractères jusqu'à ce qu'il rencontre soit un autre caractère non vierge, soit un CR/LF. Lorsque les caractères sont lus, le Turbo Pascal combine les caractères en une chaîne de caractères alphanumérique et convertit la chaîne de caractères en une valeur Integer ou Real, selon le type de variable utilisé. Si la conversion réussit, le numéro est attribué à la variable; en cas d'échec, le Turbo Pascal a généré une erreur d'entrée/sortie.

Pour savoir comment les nombres sont lus à partir de fichiers texte, examinez le fichier texte numérique TEST.DAT dans la figure suivante :

 11    27.57   6.4144900000E+03
 21    50.87   1.1843390000E+07
 31    74.17   1.2547890000E+07
 41    97.47   2.1259870000E+07
 51   120.77   2.8139002400E+07
 61   144.07   3.8654741700E+07
 71   167.37   4.4412450000E+07
 81   190.67   4.9852140000E+07
 91   213.97   5.0214578825E+07
101   273.27   5.5274590000E+07

Le fichier contient trois colonnes de nombres. Les premières colonnes sont Integer, les deuxièmes nombres Real au format décimal et les troisièmes nombres Real en notation scientifique. Vous pouvez lire les trois nombres sur chaque ligne du fichier en utilisant les instructions suivantes :

  1. Read(TxtFile,i);
  2. Read(TxtFile,r1);
  3. Read(TxtFile,r2);

ou en utilisant la déclaration unique équivalente :

  1. ReadLn(TxtFile,i,r1,r2);

Le Turbo Pascal attribue le premier nombre trouvé dans une ligne à la variable i de type de données Integer et les deux prochains nombres à la variable r1 et r2 de type de données Real. Le programme suivant contient une routine lisant le fichier numérique TEST.DAT et calcule la moyenne de chaque colonne de chiffres :

  1. Program CaluleLaMoyenne;
  2. Var
  3.  f:Text;
  4.  i,count:Integer;
  5.  imean,r1,r2,r1mean,r2mean:Real;
  6. BEGIN
  7.  Assign(f,'TEST.DAT');
  8.  Reset(f);
  9.  count:=0;imean:=0;r1mean:=0;r2mean:=0;
  10.  While Not Eof(f) do Begin
  11.   ReadLn(f,i,r1,r2);
  12.   WriteLn(1:10,' ',r1:10:3,' ',r2:10:3);
  13.   count:=count+1;
  14.   imean:=imean+i;
  15.   r1mean:=r1mean+r1;
  16.   r2mean:=r2mean+r2;
  17.  End;
  18.  imean:=imean/count;
  19.  r1mean:=r1mean/count;
  20.  r2mean:=r2mean/count;
  21.  WriteLn;
  22.  WriteLn(imean:10:3,' ',r1mean:10:3,' ',r2mean:10:3);
  23.  Close(f);
  24. END.

Ce programme introduit la fonction standard Eof de Turbo Pascal, signifiant fin de fichier. La fonction Eof est une fonction booléenne n'étant vraie (True) que lorsque le pointeur de fichier est à la fin de votre fichier. Il peut être utilisé pour répéter les commandes d'entrée afin qu'un fichier entier soit traité du début à la fin. Dans l'exemple précédent, l'instruction :

  1. While Not Eof(f)do

indique à Turbo Pascal d'exécuter le bloc de code suivant jusqu'à ce que Eof(f) renvoie TRUE, c'est-à-dire jusqu'à ce que le dernier caractère du fichier soit lu.

La fonction Eoln teste la fin d'une ligne. La fonction Eoln est vrai dans deux conditions : lorsque le pointeur de fichier rencontre un retour chariot et lorsque le pointeur de fichier atteint la fin d'un fichier. Vous pouvez utiliser la fonction Eoln pour lire chaque caractère d'une ligne un par un, comme le montre l'exemple suivant :

  1. Program ReadChar;
  2. Var
  3.  f:Text;
  4.  i:Integer;
  5.  Ch:Char;
  6. BEGIN
  7.  Assign(f,'TEST.TXT');
  8.  Reset(f);
  9.  While Not Eof(f) do Begin { Continuer pour tout le fichier }
  10.   While Not Eoln(f)do Begin { Continuer jusqu'au prochain retour chariot }
  11.    Read(f,Ch);
  12.    WriteLn(Ch);
  13.   End;
  14.   ReadLn(f); { Passer le retour chariot au début de la ligne suivante }
  15.  End;
  16.  Close(f);
  17. END. 

La fonction Eoln lit les caractères sur une ligne et les écrit sur des lignes séparées.

SeekEof et SeekEoln

Pour vous donner encore plus de contrôle sur les fichiers texte, Turbo Pascal propose SeekEof et SeekEoln. Comme leurs homologues Eof et Eoln, SeekEof renvoie TRUE à la fin d'un fichier et SeekEoln renvoie TRUE à la fin d'une ligne. Ces fonctions ont une capacité unique d'ignorer les caractères ASCII compris entre 0 et 32 lors des tests de fin de fichier ou de fin de ligne. Cette intervalle comprend les caractères de contrôle ASCII standard ainsi que le caractère vide. Par conséquent, la fonction SeekEof renvoie TRUE même s'il reste des caractères dans le fichier, tant que ces caractères sont vides ou des codes de contrôle.

Erreurs de saisie numérique

Si le format d'un nombre lu à partir d'un fichier texte est incorrect, le programme produit une erreur d'entrée/sortie. Par exemple, lire le nombre 50 000 dans une variable Integer provoquerait une erreur car le plus grand Integer autorisé est 32 767. De même, la lecture du nombre 32.1 dans une variable Integer provoquerait une erreur à cause de la décimale, ce qui est illégal pour Integer. Les variables Real posent moins de restrictions puisque les nombres peuvent être lus avec ou sans décimale ou en notation scientifique.

Écriture de fichiers texte

Un fichier texte peut être utilisé pour la sortie après avoir été préparé avec les procédures Rewrite ou Append. Une fois préparées, les procédures Write ou WriteLn produisent le fichier. Le premier paramètre de ces procédures, l'identificateur de fichier texte, indique à Turbo Pascal où envoyer les données. Il est suivi d'un nombre quelconque d'identificateurs de variables ou de valeurs littérales à afficher. Par exemple, l'instruction suivante écrit la ligne «Sylvain» dans le fichier suivant identifié comme TxtFile :

  1. Name:='Sylvain';
  2. i:=21;
  3. WriteLn(TxtFile,name,' ',i);

La procédure Write et WriteLn produisent normalement des valeurs sans aucun formatage spécial. L'ajout d'un deux-points et d'un nombre après le paramètre spécifie cependant que la valeur doit être justifiée à droite dans un espace défini par le nombre. Par exemple, ces déclarations :

  1. Name:='Sylvain';
  2. WriteLn(Name);
  3. WriteLn(Name:20);
  4. WriteLn(Name:4);

résultent en la sortie suivante :

Sylvain
             Sylvain
Sylvain

La première instruction WriteLn n'est pas formatée, donc la valeur est écrite justifiée à gauche. La deuxième instruction indique à Turbo Pascal de créer un champ de 20 caractères de large et de justifier à droite la valeur dans le champ. Le nom «Sylvain» étant composé de sept caractères, le Turbo Pascal justifie à droite le nom en le précédant de 13 espaces. La troisième instruction est également formatée, mais le champ avec 4 est inférieur à la longueur de la valeur elle-même. Lorsque cela se produit, la mise en forme n'a aucun effet. Les Integer suivent le même format de sortie que String : un simple deux-points suivi du nombre d'espaces pour justifier à droite le nombre. Le Real, cependant, peut être formaté avec un ou deux paramètres. Le premier paramètre détermine la largeur du champ dans lequel le nombre sera justifié à droite, et le second détermine le nombre de décimales. Le programme suivant montre différents formats pour les nombres Real et affiche leurs résultats :

  1. Program RealFormat;
  2. Var
  3.  r:Real;
  4. BEGIN
  5.  r:=123.23;
  6.  WriteLn(r);       { Resultat: 1.232300000E+02 }
  7.  WriteLn(r:0);     { Resultat: 1.2E+02 }
  8.  WriteLn(r:10);    { Resultat: 1.2323E+02 }
  9.  WriteLn(r:10:2);  { Resultat: 123.23 }
  10.  WriteLn(r:0:0);   { Resultat: 123 }
  11. END.

Fichiers disque et tampons

La lecture et l'écriture d'un fichier sur disque sont deux des opérations les plus lentes effectuées par un ordinateur. Le temps nécessaire à un unité de disque pour localiser les données semble être des années pour un microprocesseur. De petits morceaux de mémoire appelés tampons sont mis de côté pour les données à utiliser dans les opérations de disque. Les tampons accélèrent le traitement en réduisant le nombre de lectures et d'écritures sur le disque. Par exemple, supposons qu'un programme lit cinq caractères dans un fichier texte avec les instructions suivantes :

  1. Read(TxtFile,Ch1);
  2. Read(TxtFile,Ch2);
  3. Read(TxtFile,Ch3);
  4. Read(TxtFile,Ch4);
  5. Read(TxtFile,Ch5);

Si l'entrée n'est pas mise en mémoire tampon, le programme doit aller sur le disque pour chaque caractère lu. Si, cependant, le programme récupère les cinq caractères avec la première instruction Read et les entrepose dans une mémoire tampon, la mémoire tampon peut distribuer les caractères aux quatre prochaines instructions Read sans avoir à accéder au disque.

Le Turbo Pascal fournit des fichiers texte avec un tampon standard de 128 octets. Chaque fois qu'un programme lit des données à partir d'un fichier texte, le tampon est rempli de 128 octets, même si vous n'en demandez que 10. Bien sûr, vous ne saurez jamais que les octets supplémentaires sont en mémoire puisque Turbo Pascal s'occupe de tout cela pour vous.

Lorsque vous traitez des fichiers texte volumineux, la mémoire tampon standard de 128 octets est inadéquate. Le Turbo Pascal vous permet d'étendre le tampon d'un fichier texte avec la procédure SetTextBuf, dans laquelle vous spécifiez une variable à utiliser comme tampon, par exemple :

  1. Var
  2.  f:Text;
  3. Begin
  4.  Assign(f,'TEST.DAT');
  5.  SetTextBuf(f,Buffer);
  6.  Reset(f);
  7. End;

Ce code affecte un tampon de 512 octets au fichier texte F, bien que vous ayez pu agrandir le tampon. Attention cependant à ne pas appeler SetTextBuf une fois que vous avez ouvert un fichier, sinon vous perdrez probablement des données. Assurez-vous également que le tampon est déclaré globalement; si vous utilisez un tampon local; vous risquez de perdre des données si la variable locale est ignorée.

Vider un fichier

Lors de l'écriture dans un fichier tamponné, le Turbo Pascal envoie en fait les données à un tampon de sortie. Lorsque la mémoire tampon est remplie, tout le contenu est écrit sur le disque en une seule fois.

Pour forcer Turbo Pascal à vider un tampon de sortie avant qu'il ne soit rempli, utilisez la procédure Flush. L'instruction Flush(f) force toutes les données du tampon f à être enregistrées immédiatement sur le disque, éliminant ainsi toute possibilité que les données soient perdues. La fermeture d'un fichier de sortie vide automatiquement le tampon de sortie.

Fichiers typés

Les fichiers de typés sont des fichiers contenant des données d'un type particulier, tels que Integer, Real, Record,... Les fichiers de valeurs peuvent rendre votre programmation plus facile et plus efficace. En fait, les fichiers typés fournissent une entrée et une sortie beaucoup plus rapides que les fichiers texte.

Contrairement aux fichiers texte, n'étant pas structurés, les fichiers typés ont une structure rigide dépendant du type de données qu'ils contiennent et étant définie par celui-ci. Dans l'exemple suivant, l'identificateur de fichier f est déclaré comme un fichier typé appelé File of Real :

  1. Program TypedFile;
  2. Var
  3.  f:File Of Real;

La déclaration indique à Turbo Pascal que ce fichier sera utilisé pour entreposer uniquement les nombres Real. En fait, ce fichier entreposera les numéros Real dans le même format dans lequel ils sont entreposés dans la RAM. C'est là que réside la raison pour laquelle les fichiers saisis sont rapides : parce qu'ils contournent tous les processus de traduction et de conversion que subissent les données dans les fichiers texte, ils peuvent transférer les données directement en mémoire.

Par exemple, un fichier déclaré de type Integer sait qu'il est entreposé uniquement en Integer : les données qu'il contient ne doivent pas être converties en Integer avant de pouvoir être traitées.

Enregistrements et fichiers non typés

Comme ils ne sont pas constitués de lignes, comme le sont les fichiers texte, les fichiers tapés ne peuvent pas utiliser les instructions ReadLn et WriteLn. Mais si les fichiers typés ne sont pas organisés en lignes, comment sont-ils organisés ? Les fichiers non typés sont organisés en enregistrements, chaque élément de données représentant un enregistrement. La longueur d'un enregistrement correspond au nombre d'octets requis pour entreposer le type de données. Dans l'exemple précédent, le fichier entrepose des nombres de type Real. Puisqu'un nombre Real nécessite six octets dans Turbo Pascal, la longueur d'enregistrement du fichier est de six octets : les six premiers octets du fichier contiennent le premier enregistrement (numéro Real), les six suivants contiennent le deuxième enregistrement, par la suite. Pour Integer, les nombres ne nécessitant que deux octets, un fichier non typé est organisé en enregistrements de deux octets.

Le programme suivant montre comment un fichier typé est déclaré, utilisé pour la sortie, puis utilisé pour l'entrée :

  1. Program ReadFile;
  2.  
  3. Uses CRT;
  4.  
  5. Var
  6.  r:Real;
  7.  F:File Of Real;
  8.  
  9. BEGIN
  10.  ClrScr;
  11.  Assign(f,'REAL.DAT');
  12.  Rewrite(f);
  13.  R:=100.234;
  14.  Write(f,r);
  15.  r:=32.23;
  16.  Write(f,r);
  17.  r:=7874.40;
  18.  Write(f,r);
  19.  Reset(f);
  20.  While Not Eof(f)do Begin
  21.   Read(f,r);
  22.   WriteLn(r:0:3);
  23.  End;
  24.  WriteLn;
  25. END. 

Ce programme écrit trois nombres Real. Étant donné que chaque nombre Real nécessite six octets, la taille du fichier est de 18 octets. Vous pouvez le confirmer avec la commande DIR au prompt DOS.

Chaînes de caractères et fichiers typés

Les fichiers typés peuvent également être de type String, mais c'est très différent d'un fichier texte. Même si les deux sont conçus pour contenir des chaînes de caractères, la manière dont ils entreposent les chaînes est ce qui les sépare. Prenons l'exemple suivant :

  1. Program OutputCompare;
  2. Type
  3.  Str10=String[10];
  4. Var
  5.  TxtFile:Text;
  6.  StringFile:File of Str10;
  7.  s:Str10;
  8.  
  9. BEGIN
  10.  WriteLn('Reecriture de OUTPUT.TXT');
  11.  Assign(TxtFile,'OUTPUT.TXT');
  12.  Rewrite(TxtFile);
  13.  
  14.  WriteLn('Reecriture de OUTPUT.STR');
  15.  Assign(StringFile,'OUTPUT.STR');
  16.  Rewrite(StringFile);
  17.  
  18.  s:='ABCD';
  19.  
  20.  WriteLn('Ecriture de OUTPUT.TXT');
  21.  Write(TxtFile,s);
  22.  WriteLn('Ecriture de OUTPUT.STR');
  23.  Write(StringFile,s);
  24.  WriteLn('Fermeture des fichiers.');
  25.  Close(TxtFile);
  26.  Close(StringFile);
  27.  WriteLn;
  28. END. 

Le programme déclare deux fichiers, un Text et l'autre de type File of Str10. Les deux fichiers sont préparés pour la sortie et la chaîne de caractères 'ABCD' est écrite à la fois. C'est là que s'arrête la similitude.

Dans le cas du fichier Text, le Turbo Pascal écrit les lettres A, B, C et D et rien de plus, comme indiqué ici :

Dans le fichier typé, cependant, le Turbo Pascal entrepose la chaîne de caractères dans sa forme complète : l'octet de longueur, les caractères légitimes dans la chaîne de caractères (ABCD) et tous les caractères inutiles remplissant les six octets restants d'entreposage, comme indiqué ici :

Cet exemple montre que les fichiers String nécessitent plus d'espace que les fichiers texte car le Record inclut l'octet de longueur de chaîne de caractères ainsi que tous les octets de déchets.

Fichiers typés et vitesse

Les données entreposées dans un fichier typé ont exactement la même forme que lorsqu'elles sont entreposées dans la RAM. Ce fait conduit à une augmentation considérable des performances d'entrée/sortie par rapport au traitement de fichiers texte. Pourquoi ? Parce que chaque fois que Turbo Pascal utilise un fichier texte, un peu de temps est perdu pendant que les nombres sont convertis en caractères et inversement et les chaînes de caractères sont dépouillées de leur octet de longueur et de tous les octets inutilisés. Les données des fichiers typés, par contre, peuvent être lues directement dans la RAM sans aucune transformation. Cette situation signifie moins de travail pour l'ordinateur et, par conséquent, un traitement plus rapide.

Fichiers typés plus complexes

Tout comme vous pouvez définir vos propres types de données, vous pouvez également définir un fichier pour contenir ces types de données. Par exemple, un enregistrement de type de données Client avec les champs Nom, Adresse et Telephone peut être entreposé dans un fichier tel que défini dans le programme suivant :

  1. Program FichEnr;
  2.  
  3. Uses CRT;
  4.  
  5. Type
  6.  ClientRec=Record
  7.   Nom:String[30];
  8.   Adresse:String[40];
  9.   Telephone:String[15];
  10.  End;
  11.  
  12. Var
  13.  Client:ClientRec;
  14.  FicheClient:File Of ClientRec;
  15.  
  16. Procedure CreateFile;
  17. Var
  18.  I:Integer;
  19. Begin
  20.  Assign(FicheClient,'CLIENT.DAT');
  21.  Rewrite(FicheClient);
  22.  With Client do Begin
  23.   Nom        := 'Sylvain Maltais';
  24.   Adresse    := 'Laval, Quebec';
  25.   Telephone  := '(555) 123-1234';
  26.  End;
  27.  Write(FicheClient,Client);
  28.  With Client do Begin
  29.   Nom        := 'Rejean Tremblay';
  30.   Adresse    := 'Alma, Quebec';
  31.   Telephone  := '(555) 234-2134';
  32.  End;
  33.   Write(FicheClient,Client);
  34.  With Client do Begin
  35.   Nom        := 'Daniel Fortin';
  36.    Adresse    := 'Sept-Iles, Quebec';
  37.   Telephone  := '(555) 345-1234';
  38.  End;
  39.  Write(FicheClient,Client);   
  40.  Close(FicheClient);
  41. End;
  42.  
  43. BEGIN
  44.  ClrScr;
  45.  CreateFile;
  46.  Assign(FicheClient,'CLIENT.DAT');
  47.  Reset(FicheClient);
  48.  While Not Eof(FicheClient) do Begin
  49.   Read(FicheClient,Client);
  50.   With Client do Begin
  51.    WriteLn(Nom,' ',Adresse,' ',Telephone);
  52.   End;
  53.  End;
  54.  Close(FicheClient);
  55.  WriteLn;
  56. END.

Étant donné que le fichier est déclaré du même type que l'enregistrement Client, il est possible de lire et d'écrire un enregistrement complet à la fois. Il augmente la vitesse car vous n'avez pas besoin de lire ou d'écrire chaque élément de l'enregistrement séparément.

Fichiers non typés

Les fichiers non typés sont un outil particulièrement puissant fourni par Turbo Pascal. Alors que les fichiers texte supposent qu'un fichier se compose de lignes terminées par CR/LF, et que les fichiers typés supposent qu'un fichier se compose d'un type particulier de structure de données, les fichiers non typés ne font aucune hypothèse sur la structure des données dans un fichier. Vous pouvez lire les données d'un serveur de fichiers non typé dans n'importe quel type de données souhaité.

Étant donné que Turbo Pascal ne fait aucune hypothèse sur le format des données, le transfert du disque vers votre structure de données est immédiat. C'est pourquoi les fichiers non typés sont utilisés pour les applications nécessitant une entrée et une sortie à haute vitesse.

L'exemple suivant, copiant le contenu d'un fichier dans un autre, illustre une utilisation typique de fichiers non typés. Comme vous pouvez le voir, deux identificateurs de fichier, SourceFile et TargetFile, sont déclarés de type File. Les fichiers non typés tirent leur nom du fait que le mot réservé File n'est pas suivi d'une spécification de type, comme c'est le cas avec les fichiers typés.

  1. Program CopyFile;
  2.  
  3. Uses CRT;
  4.  
  5. Var
  6.  SourceFile,TargetFile:File;
  7.  RecordsRead:Integer;
  8.  Buffer:Array[1..1000]of Byte;
  9.  
  10. BEGIN
  11.  ClrScr;
  12.  If ParamCount<>2 Then Begin
  13.   WriteLn('CopyFile [DuFichier] [VersFichier]');
  14.   Halt;
  15.  End;
  16.  Assign(SourceFile,ParamStr(1));
  17.  {$I-}Reset(SourceFile,1);
  18.  If IOResult<>0 Then Begin
  19.   WriteLn(ParamStr(1),' est introuvable.');
  20.   Halt;
  21.  End;
  22.  Assign(TargetFile,ParamStr(2));
  23.  Rewrite(TargetFile,1);
  24.  WriteLn('. = 1 000 octets copies.');
  25.  BlockRead(SourceFile,Buffer,SizeOf(Buffer),RecordsRead);
  26.  While RecordsRead > 0 do Begin
  27.   Write('.');
  28.   BlockWrite(TargetFile,Buffer,RecordsRead);
  29.   BlockRead(SourceFile,Buffer,SizeOf(Buffer),RecordsRead);
  30.  End;
  31.  Close(SourceFile);
  32.  Close(TargetFile);
  33.  WriteLn;
  34. END.

Contrairement aux fichiers texte et types, les instructions Reset et Rewrite pour les fichiers non typés peuvent prendre un deuxième paramètre, la taille de l'enregistrement. Par exemple, l'instruction :

  1. Reset(SourceFile,1);

prépare le fichier à lire et spécifie que la longueur de l'enregistrement est de 1 octet. Cela a du sens puisque la structure de données est un tableau de Byte. Si la structure de données était un tableau de Integer, vous pouvez définir la longueur de l'enregistrement sur 2. Bien que Turbo Pascal ne vous oblige pas à faire correspondre la longueur de l'enregistrement à la taille du type de données que vous utilisez, cela facilite la programmation. Notez que si vous ne spécifiez pas de longueur d'enregistrement dans les instructions Reset ou Rewrite, le Turbo Pascal attribue une longueur d'enregistrement par défaut de 128 octets. La lecture et l'écriture dans des fichiers non typés nécessitent deux procédures standard spéciales Turbo Pascal : BlockRead et BlockWrite. Dans l'exemple précédent, l'instruction :

  1. BlockRead(SourceFile,Buffer,SizeOf(Buffer),RecordsRead);

prend quatre paramètres. L'identificateur de fichier SourceFile est le premier. Le deuxième paramètre spécifie la structure de données dans laquelle les données seront placées. Dans l'exemple, la structure de données est le tableau d'octet Buffer.

Le troisième paramètre spécifie le nombre d'enregistrements à lire. Dans l'exemple, la taille de l'enregistrement a été définie sur 1 octet par l'instruction Reset. La structure de données Buffer, cependant, a une longueur de 1 000 octets. Pour remplir complètement Buffer, vous devez alors lire 1 000 enregistrements. Vous pouvez simplement écrire le nombre 1 000 comme troisième paramètre, mais la fonction standard SizeOf de Turbo Pascal offre une meilleure alternative. La fonction SizeOf renvoie le nombre d'octets utilisés par une structure de données spécifiée. Par exemple, si i est un Integer, alors SizeOf(i) renvoie la valeur 2 car Integer nécessite deux octets d'entreposage. Dans l'exemple, l'instruction SizeOf(Buffer) renvoie 1 000 car c'est le nombre d'octets que Buffer utilise. En utilisant la fonction SizeOf, vous pouvez modifier la taille du tampon sans avoir à modifier les instructions BlockRead.

Le quatrième et dernier paramètre de l'instruction BlockRead est la variable RecordsRead de type de données Integer. Lorsque l'instruction BlockRead s'exécute, elle tente de lire le nombre d'enregistrements spécifié (1 000 dans l'exemple). Cependant, si le pointeur de fichier est proche de la fin du fichier, vous pouvez en fait lire moins de 1 000 enregistrements. La variable RecordsRead vous indique exactement combien d'enregistrements ont été lus par l'instruction BlockRead. Lorsque RecordsRead est égal à zéro, la fin du fichier a été atteinte.

La procédure BlockWrite fonctionne à peu près de la même manière que BlockRead, sauf qu'il n'y a que trois paramètres. L'identificateur de fichier vient en premier, suivi de la structure de données utilisée pour la sortie. Le troisième paramètre est le nombre d'enregistrements à écrire dans le fichier. Dans l'exemple de programme CopyFile, la variable RecordsRead spécifie le nombre d'enregistrements à écrire car vous souhaitez écrire exactement ce qui a été lu.

Procédures pour les fichiers typés et non typés

Les fichiers non textuels (c'est-à-dire les fichiers typés et non typés) sont également appelés fichiers à accès aléatoire, ce qui signifie que les enregistrements d'un fichier sont accessibles dans un ordre non quantitatif. Si vous le souhaitez, vous pouvez d'abord lire le troisième enregistrement, puis le dixième et le premier après. Cela se fait en deux étapes : placez d'abord le pointeur de fichier sur l'enregistrement correct, puis lisez l'enregistrement. Ceci est illustré dans le programme suivant, créant un fichier de données typé, puis lit les enregistrements dans un ordre non séquentiel :

  1. Program DataBaseFile;
  2.  
  3. {$v-}
  4.  
  5. Uses CRT;
  6.  
  7. Type
  8.  MaxStr=String[255];
  9.   CustRec=Record
  10.    Name:String[30];
  11.    Age:Integer;
  12.    Income:Real;
  13.   End;
  14.   
  15. Var
  16.  Cust:CustRec;
  17.  CustFile:File Of CustRec;
  18.  
  19. Procedure AddRec(NameIn:MaxStr;AgeIn:Integer;IncomeIn:Real);Begin
  20.  With Cust do Begin
  21.   Name:=NameIn;
  22.   Age:=AgeIn;
  23.   Income:=IncomeIn;
  24.   Write(CustFile,Cust);
  25.  End;
  26. End;
  27.  
  28. Procedure DumpRec;Begin
  29.  WriteLn;
  30.  With Cust Do Begin
  31.   WriteLn('Nom: ',Name);
  32.   WriteLn('Age:',Age);
  33.   WriteLn('Revenu: ',Income:0:0);
  34.  End;
  35. End;
  36.  
  37. BEGIN
  38.  ClrScr;
  39.  Assign(CustFile,'CUSTFILE.DAT');
  40.  Rewrite(CustFile);
  41.  AddRec('Maltais',30,23000.0);
  42.  AddRec('Fortin',65,34000.0);
  43.  AddRec('Potvin',21,18000.0);
  44.  
  45.  Reset(CustFile);
  46.  
  47.  WriteLn('Le nombre d''enregistrements dans le fichier est ',FileSize(CustFile));
  48.  
  49.  Seek(CustFile,2);
  50.  WriteLn;
  51.  WriteLn;
  52.  WriteLn('C''est le numero d''enregistrement : ',FilePos(CustFile)+1);
  53.  Read(CustFile,Cust);
  54.  DumpRec;
  55.  
  56.  Seek(CustFile,0);
  57.  WriteLn;
  58.  WriteLn;
  59.  WriteLn('C''est le numero d''enregistrement : ',FilePos(CustFile)+1);
  60.  Read(CustFile,Cust);
  61.  DumpRec;
  62.  
  63.  Seek(CustFile,1);
  64.  WriteLn;
  65.  WriteLn;
  66.  WriteLn('C''est le numero d''enregistrement : ',FilePos(CustFile)+1);
  67.  Read(CustFile,Cust);
  68.  DumpRec; 
  69.  
  70.  Seek(CustFile,0);
  71.  AddRec('Tremblay',32,47000.0);
  72.  
  73.  Seek(CustFile,0);
  74.  WriteLn;
  75.  WriteLn;
  76.  
  77.  WriteLn('C''est le numero d''enregistrement : ',FilePos(CustFile)+1);
  78.  Read(CustFile,Cust);
  79.  DumpRec;
  80.  
  81.  Close(CustFile);
  82. END.

Les instructions Seek déplace le pointeur de fichier au début du troisième enregistrement. Notez que le troisième enregistrement est appelé numéro 2 dans l'instruction Seek car les fichiers de type Turbo Pascal commencent par l'enregistrement 0. Lorsque le pointeur de fichier est en place, vous pouvez lire l'enregistrement comme vous le feriez normalement. Une fois la Read exécutée, le pointeur de fichier est automatiquement déplacé au début de l'enregistrement suivant. Dans ce cas, le troisième enregistrement est le dernier enregistrement du fichier. Toute tentative de lecture au-delà de la fin du fichier entraîne une erreur d'entrée/sortie.

Un exemple de Read non séquentiel est illustré par les deux instructions suivantes :

  1. Seek(CustFile,2);
  2. Read(CustFile,Cust);

Deux autres fonctions standard, FileSize et FilePos, sont également utilisées. La fonction FileSize renvoie le nombre total d'enregistrements dans le fichier; FilePos renvoie la position actuelle du pointeur de fichier.

Une fonctionnalité particulièrement puissante des fichiers à accès aléatoire est la possibilité de mettre à jour les enregistrements à tout moment du fichier. Ceci est démontré à la fin de l'exemple de programme précédent (intitulé DataBaseFile), où les informations du premier enregistrement sont modifiées puis affichées. Ce qui est particulièrement remarquable, c'est que la procédure Write est utilisée sans instruction Rewrite précédente. Cela semble aller à l'encontre de la règle selon laquelle un fichier doit être préparé avec Rewrite avant de pouvoir y ajouter des données. Pour les fichiers non textuels, la commande Rewrite n'est nécessaire que pour créer le fichier. Une fois que le fichier existe, la commande Reset vous permet à la fois de lire et d'écrire dans le fichier.

Effacer et renommer des fichiers

La gestion sophistiquée des fichiers nécessite la possibilité de renommer et d'effacer des fichiers sans revenir au prompt DOS. Le Turbo Pascal fournit deux procédures pour faire exactement cela. Pour renommer un fichier, affectez d'abord un fichier à une variable de fichier, puis appelez la procédure Rename avec le nouveau nom spécifié :

  1. Assign(f,'FILE.OLD');
  2. Rename(f,'FILE.NEW');

La procédure Erase fonctionne essentiellement de la même manière. Attribuez le fichier disque à un identificateur de fichier, puis appelez la procédure Erase :

  1. Assign(f,'FILE.OLD');
  2. Erase(f);

Le programme suivant fournit une méthode simple pour renommer et effacer des fichiers. Lorsque vous démarrez le programme, trois choix sont proposés: renommer un fichier, effacer un fichier ou quitter :

  1. Program FileControl;
  2.  
  3. Uses CRT;
  4.  
  5. Var
  6.  File1:File;
  7.  Name1,Name2:String[255];
  8.  Choice:Char;
  9. BEGIN
  10.  ClrScr;
  11.  Repeat
  12.   WriteLn('R)enommer, E)ffacer, Q)uitter');
  13.   Case UpCase(Choice)of
  14.    'R':Begin
  15.     Write('Nom de fichier a renommer :');
  16.     ReadLn(Name1);
  17.     Write('Nouveau nom pour le fichier :');
  18.     ReadLn(Name2);
  19.     Assign(File1,Name1);
  20.     Assign(File1,Name2);
  21.    End;
  22.    'E':Begin
  23.     Write('Nom de fichier à effacer :');
  24.     ReadLn(Name1);
  25.     Assign(File1,Name1);
  26.     Erase(File1);
  27.    End;
  28.   End;
  29.  Until Upcase(Choice)='Q';
  30. END.

Faites une sélection en tapant R, E ou Q et en appuyant sur ENTER. Lorsque vous renommez un fichier, entrez le nom du fichier existant ainsi que le nouveau nom du fichier. Pour effacer un fichier, il vous suffit de saisir le nom du fichier à écraser.



Dernière mise à jour : Dimanche, le 16 mai 2021