Les Fichiers en Turbo Pascal

March 25, 2018 | Author: Naoufel Charfeddine | Category: Computer File, Computer Program, Text File, Computer Data Storage, Operating System


Comments



Description

Chapitre 5 - Les fichiers en Turbo Pascal1 Intérêt des fichiers Les entrées-sorties, c'est-à-dire la communication d'informations entre la mémoire d'un ordinateur et ses périphériques ( unités de disques, dérouleurs de bandes, imprimantes, clavier, écran, etc. ) sont modélisées de façon abstraite à l'aide de la notion de fichier. Un fichier peut être considéré comme une suite éventuellement vide de composants de même type déposée sur un support quelconque hors mémoire. C'est le seul moyen offert aux programmes pour communiquer avec le monde extérieur pendant leur exécution. Tout programme manipule l'information à travers des variables qui résident dans la mémoire centrale de l’ordinateur. L’information n’existe donc que la durée de l’exécution du dit programme. Les fichiers sont donc aussi le seul moyen : - de sauvegarder l'information entre plusieurs exécutions, - de faire communiquer entre eux plusieurs programmes, qu’ils soient sur une même machine ou des machines différentes, - de transmettre des données entre plusieurs machines. Les modes de représentations physiques des fichiers varient énormément d'un ordinateur à l'autre. De plus les fichiers sont du domaine du système d'exploitation et chaque langage met donc en oeuvre une gestion de fichier adaptée au système sous lequel il est installé, ce qui posera un grave problème de portabilité des programmes d’une machine à une autre. Le seul type de fichier qui soit presque toujours transférable sans trop de difficulté entre deux matériels est le fichier séquentiel de caractères fréquemment nommé fichier texte. Il est donc difficile d'intégrer la notion de fichier dans un langage de programmation sans courir le risque de choisir un concept trop lié à l'architecture d'un ordinateur ou d'une famille d'ordinateurs particuliers. 2 Les formats de fichiers En mémoire centrale, l’information est codée en binaire. Outre le fait que l’unité centrale réalise tous les calculs avec des circuits électroniques fonctionnant en logique binaire, l’intérêt principal de ce codage est que la taille de la zone mémoire nécessaire à stocker toutes les valeurs possibles d’une variable est fixe. Cette taille est déterminée par le compilateur lors de la déclaration de type de cette variable. Par exemple un entier occupe 2 cases mémoire ( 2 octets ou 16 bits sur un micro-ordinateur ) quelle que soit sa valeur, qui est limitée à ±32767 ; en effet avec 16 bits, on a 216 combinaisons soit 65536 valeurs possibles. Par convention l’ensemble des Integer est “ centré sur zéro ”, d’où un domaine de définition de -32768 à 32767. De la même façon, une variable de type Word est aussi codée sur 16 bits, mais le domaine de définition n’inclut que des valeurs positives ou nulles soit de 0 à 65535. Il est important de se souvenir que le codage utilisé dépend du matériel ( micro-ordinateur, mini-ordinateur... ) et du langage utilisé. Si les informations étaient représentées en mémoire en clair, par exemple une série de chiffres décimaux, la place occupée par une variable serait bien supérieure ; il faudrait probablement réserver 5 cases mémoire pour un entier ( une case par chiffre ) sans compter le signe. De plus la taille effectivement occupée dans la zone réservée dépend de la valeur de la variable. La valeur 1 occuperait une seule case sur les cinq et la valeur 32000 occuperait les cinq cases. Il faudrait donc ajouter une information supplémentaire sur le nombre de cases effectivement occupées dans la zone réservée. Les fichiers - 1 Lors de l’écriture d’une variable dans un fichier, ou de sa relecture ultérieure, il convient donc de préciser si l’on désire ou non une conversion entre le format binaire interne à la machine et le format usuel utilisé par les humains pour représenter l’information. On distingue donc deux types de fichiers : binaires et textes. Chacun de ces deux types de fichiers présente des avantages et des inconvénients qui font que ni l’un ni l’autre ne peut être abandonné. - les fichiers binaires, où l’information est déposée par une simple recopie de la zone mémoire associée à la variable. A la relecture, le contenu de la zone mémoire est directement relu depuis le disque. Ces fichiers sont souvent nommés fichiers à accès direct car le temps d'accès à chaque composante est sensiblement constant, ce qui n'est absolument pas le cas dans les fichiers textes. Un autre avantage majeur de ces fichiers est la possibilité de lire et d'écrire en même temps sur le même périphérique, ce qui simplifiera beaucoup les opérations de modifications des informations. Cette extension est très simplement obtenue sachant que le fichier est une série de composantes de même type et donc de même taille, ce qui permet au langage de calculer la position physique sur le support d'une composante quelconque à partir de son numéro d'ordre et de sa taille. Un fichier binaire est donc une extension de la notion de tableau à une dimension, extensible par une extrémité. Le seul moyen d'obtenir ce résultat est de communiquer avec le support en format binaire, c’est-à-dire comme une copie exacte du contenu de la mémoire pour la variable à échanger avec ce support. Une conséquence quelle fois gênante est qu'un tel fichier ne peut contenir que des composantes de même type et ne pourra être traité qu'une composante à la fois. Le fait que les langages n'inscrivent pas au début d’un fichier la nature et la taille des composantes, conduit au problème qu'il n'est généralement pas possible de faire relire à un langage un fichier binaire créé par un autre langage, ni même par le même langage si l'on ne connaît pas la nature ( le type ) des composantes du fichier. Ces fichiers sont donc parfaitement adaptés à une gestion transactionnelle de l'information, où l'on réalise très fréquemment des mises à jour. Il importera ensuite de convertir ces fichiers en format texte si l'on désire échanger leur contenu avec d'autres programmes ou l'archiver. - les fichiers textes, où l’information est convertie du format interne en format lisible par un humain lors de l’écriture. A la relecture, l’opération de codage en binaire sera effectuée pour convertir de nouveau la série de caractères qui représentent la valeur vers le format interne à la machine. Un fichier texte est un modèle pour tout périphérique d'ordinateur qui est toujours un support sur lequel les informations ne peuvent être lues ou écrites que les unes à la suite des autres en commençant par le début et sans retour arrière possible : bandes magnétiques, imprimantes ou plus anciennement lecteurs-perforateurs de cartes perforées ou de rubans. A partir du moment où l'information est déposée en clair dans un fichier texte, la taille de chaque composante dépend de sa valeur. Il est tout à fait possible de déposer des informations de type différent dans un tel fichier, à la condition bien sur de respecter une certaine régularité afin de pouvoir relire par une boucle. De plus le programmeur a l’entière liberté d'organiser son fichier comme il le désire ; une ou plusieurs informations par ligne, avec ou sans séparateurs entre chacune ( espace, tabulations, virgule... ). Il est donc impossible de se positionner directement sur une information puisque l'on ne peut pas calculer l'endroit où elle commence, puisque cette position dépend des valeurs des composantes qui la précèdent. Il faut donc à chaque fois parcourir le fichier depuis le début jusqu'à ce que l'on ait lu cette information. Il est aussi impossible de reculer, c'est-à-dire de se remettre au début de l'information après l'avoir lue. En effet, les procédures de lecture dans un fichier ( Read ou Readln ) ne retournent pas le nombre de caractères qu'elles viennent de lire. On ne sait donc jamais de combien de caractères il faudrait reculer. Enfin, il est impossible de modifier une valeur au milieu d'un fichier texte car la place nécessaire à la nouvelle valeur sera très probablement Les fichiers - 2 différente de celle de l'ancienne. Donc, soit on écrasera le début de la valeur qui suit, soit on laissera entre les deux des caractères parasites. Reconnaissant ce fait, la plupart des langages informatiques, dont Pascal, interdisent d'ouvrir un fichier texte à la fois en lecture, pour en consulter le contenu, et en écriture pour en modifier une partie. Donc toute intervention sur un fichier texte nécessitera de le recopier intégralement dans un second, en intervenant “ au vol ” sur la valeur visée ; soit en ne la recopiant pas, ce qui a pour effet de la supprimer, soit en recopiant sa nouvelle valeur pour la changer. Ces considérations pourraient inciter à penser que les fichiers textes devraient être abandonnés au plus vite. C'est malheureusement totalement faux, puisque le format texte est bien le seul qui permette des échanges entre langages, programmes ou machines. Sans parler de l'archivage de l'information : il faut que les archives puissent être reconsultées dans de nombreuses années, quand les PC et Turbo Pascal auront disparu depuis longtemps. 3 Organisation des informations sur les mémoires de masse Bien que les primitives d’accès aux fichiers offertes par Pascal soient relativement de haut niveau, et masquent de ce fait beaucoup de détails de mise en oeuvre réelle, leur comportement est fortement influencé par la façon dont l’information est effectivement déposée sur le disque. Il n’est donc pas inutile d’avoir quelques idées sur l’organisation physique et logique de l’information sur les supports. On nomme un périphérique, tout organe extérieur à l’unité centrale de l’ordinateur capable d’échanger de l’information avec elle. On distingue les mémoires de masse et les périphériques d’entrée-sortie. Les mémoires de masse sont des organes périphériques sur lesquels il est possible de stocker des informations de manière permanente. Ces supports sont caractérisés par leur capacité de stockage et le temps moyen pour accéder à une information. Suivant les cas, ces supports peuvent être des bandes magnétiques, des disquettes, des disques dits durs, soit magnétiques, soit magnétooptiques ou optiques. Les périphériques d’entrée-sortie sont des organes de communication entre l’unité centrale et le monde extérieur. Certains sont en lecture seule, comme le clavier, d’autres à écriture seule comme l’écran ou une imprimante ou mixtes comme un modem. La communication se fait généralement en mode séquentiel, par échange de caractères. L’information y est stockée de façon semi permanente. En ce sens, l’écran et l’imprimante peuvent être considérées comme des sortes de mémoire de masse. Il n’est donc pas surprenant que les primitives utilisées pour la gestion des fichiers ( et en particulier des fichiers textes ) soient très similaires à celles qui vous connaissez déjà pour les classiques entrées-sorties à l’écran ou au clavier. 3.1 Organisation physique 3.1.1 les bandes magnétiques. Le stockage sur bandes magnétiques se fait à la suite, c'est à dire que pour accéder à une information, il faut dérouler la bande jusqu'à l'endroit où se trouve la dite information. Ce support est de grande capacité ( de 300 à 1000 M octets ) mais lent. Il tend à être remplacé par d'autres supports comme les disques optiques. L'utilisation de ce support est réservée uniquement à l'archivage. 3.1.2 les disques. La surface du disque est recouverte d'oxyde qui peut recevoir ou fournir des informations. Le disque est divisé en pistes ( cercles concentriques ) et en secteurs ( portions de piste ). Chaque secteur contient un certain nombre d'octets ( de 128 à 1024 octets ou plus suivant les technologies ). Les fichiers - 3 c'est pourquoi les transferts ( en lecture ou en écriture ) se font par au moins un secteur. Pascal garde la trace des accès au fichier grâce à un pointeur de fichier. . 4 Le type fichier en Pascal Il y a trois classes de types fichier en Pascal : typé. Ceci ne doit jamais être oublié. le bras place la tête de lecture/écriture sur la piste par un mouvement horizontal.Pour se positionner à un endroit donné du disque ( repéré par son numéro de piste et son numéro de secteur ). Les fichiers - 4 . Afin d'optimiser les accès disque.associer cette variable à un nom physique. Le temps de positionnement du bras est long ( par rapport au temps de lecture/écriture des informations ). le système d'exploitation attend d'avoir suffisamment de secteurs en attente d'écriture pour mettre en route la mécanique du disque. Pour manipuler un fichier. Chaque fois qu'un composant est écrit ou lu dans un fichier. Et vous ne vous en apercevrez qu'à la prochaine exécution.déclarer une variable particulière de type fichier sur laquelle se feront toutes les opérations. en tentant de le relire. le pointeur de fichier est automatiquement avancé sur le composant suivant. il faudra donner la suite des noms de répertoires qu'il faut traverser depuis la racine jusqu'au répertoire qui le contient. les noms de répertoires et de fichiers obéissent aux conventions du système d'exploitation utilisé. Un secteur est l'unité minimale pour un fichier. il faudra donc impérativement : . le fichier associé risque fort d'être endommagé ou incomplet. ou si votre programme s'interrompt inopinément. selon les conventions en vigueur pour le système d'exploitation. Même si un fichier a une taille inférieure à celle d'un secteur. Les noms des périphériques. la totalité de ce dernier lui sera réservé. Pour localiser un fichier sur un périphérique. rien ne prouve que les dernières informations ont effectivement été déposées sur le disque. 3.2 Organisation logique Les grandes capacités d'informations qui peuvent être stockées sur les disques nécessitent une organisation de tous ces fichiers. Donc si vous oubliez de refermer un fichier. Chaque périphérique contiendra des fichiers ou des répertoires ( un répertoire sera un espace doté d'un nom et contenant soit des fichiers. Le nombre de composants d'un fichier ( la taille du fichier ) n'est pas prédéterminer dans la déclaration du fichier. la rotation du disque permet au bout d'un certain temps de se trouver sur le secteur cherché. Les fichiers typés ou non sont les fichiers binaires. Tant que l'on n'a pas refermé un fichier. Cette localisation s'appelle le chemin ( path ). Il utilise des tampons mémoire qu'il purge à sa convenance vers le disque. soit d'autres répertoires ). non typé et texte. Un fichier est donc seulement limité par la place disponible sur le support. et celles-ci mettent en place des fichiers binaires contenant des enregistrements de type Tproduit et des chaînes de 80 caractères. Les fichiers .1 Déclarations des types fichiers type fichier : type file of type type text Un fichier binaire ( typé ) est défini par le mot réservé File Of suivi par le type des composants de ce fichier. CodeProduit : Integer . Quantite : Real .5 . chaque ligne est terminée par un indicateur de fin de ligne composée du caractère de code 13 ( CR ou retour chariot ) suivi du caractère de code 10 ( LF ou saut de ligne ). Quant au code de fin de fichier. Le fichier externe qui sera associé à une variable de type Text doit contenir de l’information en clair comme une séquence de caractères groupés en lignes . sauf un type fichier. Le type des composants d'un fichier peut être quelconque. File Of String [ 80 ] . Var FicNoms : FicProduits : ou directement FicNoms: File Of tNomDeProduit . Le code de fin de ligne est émis à la discrétion du programmeur par un ordre Writeln. Un fichier texte se déclare avec le mot réservé Text : Var OutFile : Text . il est déposé lors de l’appel à la procédure Close. CodeFourni : Integer End .4. Type tNomDeProduit = String [ 80 ] . La déclaration suivante crée une variable interne F qui sera ensuite utilisée pour accéder à un fichier externe qui devra contenir une séquence de nombres entiers codés en binaire : Var F : File Of Integer . tProduit = Record Nom : tNomDeProduit . Le fichier est lui-même terminé par une marque de fin de fichier ( EOT de code 26 ). File Of tProduit . StockMini : Real . quel que soit son type et sa structure.. Var DataFile : File . Nom : String ) ..Les fichiers sans type se déclarent avec le simple mot File. F : File Of Real . 'c:\tp\travail\essai. NomFic ) . mais il faudra à chaque fois préciser le nombre d’informations que l’on désire puisque qu’en l’absence du type des composantes. Le nom de fichier est affecté à la variable fichier interne F et toutes les opérations suivantes sur F affecteront le fichier externe dont le nom a été spécifié dans l'expression Nom.txt' ) Assign ( F . Readln ( NomFic ) .txt' ) . Assign ne doit jamais être utilisé une seconde fois sur un fichier en cours d'utilisation. Un fichier sans type est compatible avec tout autre fichier. Nom est une expression chaîne résultant en tout nom légal de fichier pour le système d'exploitation en vigueur. 'm:\essai. Assign ( T .1 Association entre une variable fichier et un fichier externe Pour pouvoir être utilisée. Assign ( F . Assign ( T . .. Les fichiers - 6 .txt’ . Il est possible de lire ou d’écrire dans de tels fichiers.. une variable fichier ( située en mémoire ) doit impérativement être initialisée en l’associant à un fichier externe grâce à un appel à la procédure Assign ( Var F : File . . Les variables de type fichier ne peuvent pas apparaître dans les affectations ou les expressions.2 Utilisation des fichiers 4. De façon interne au Pascal. 'essai. Ce sont des canaux d'entrée-sortie de bas niveau utilisés en premier lieu pour les accès directs à tout fichier disque. NomFic ) . Assign ( T . Pascal ne pourra pas le calculer lui-même. L’expression chaîne peut être une constante ou une variable convenablement initialisée ou le résultat de toute opération valide sur des chaînes de caractères comme : Var T : Text . Il convient dans ce cas de refermer le fichier avant de réaliser de nouveau l’association.dat' ) . Var NomFic : String .2. Ils utilisent par défaut une taille d'enregistrement de 128 octets.. Write ( ‘sur quel fichier va-t-on travailler ? ’ ) . une variable fichier est décrite par un enregistrement de type FileRec ( exporté par l’unité SYSTEM ).. L'emploi d'un fichier sans type sera donc préféré pour renommer ou effacer un fichier. De même un objet fichier ne peut être passé en paramètre à une procédure que par référence : un passage par valeur impliquerait une recopie du fichier externe associé. 4. Const NomFic = ‘c:\tp\travail\donnees.. ou pour toute autre opération n'impliquant pas d'entrées-sorties. Il est alors de la responsabilité du programmeur de corriger l'erreur d'entrée-sortie.2 Ouverture d’un fichier On doit ensuite procéder à l’ouverture du fichier.Const Repertoire = ‘m:’ . 4. c’est-à-dire à la création par le système d’exploitation d’une zone de transfert en mémoire. Tout autre valeur signifie qu'une erreur est survenue pendant la dernière opération d'entrée-sortie. . Selon le mode d’ouverture choisi ( lecture. Lorsque ceci est fait. c'est-à-dire lorsqu'une série d’instructions est précédée de {$I-}.3 Gestion des erreurs Tous les appels de procédures et de fonctions d'entrées-sorties font automatiquement l'objet d'un contrôle d'erreur. De la même manière. 4. ou un arrêt imprévu du programme avant cette fermeture risque de produire un fichier externe incomplet qu’il sera impossible de relire convenablement lors d’une prochaine exécution du programme. Ce n’est qu’à la fermeture du fichier que le système purgera le tampon et récupérera la mémoire utilisée. Une erreur à l’exécution se produit si vous essayez de transférer un fichier qui a été ouvert en lecture à une procédure orientée en sortie ( Write ou Writeln ). ni qu’elle vient du disque sur une opération de lecture. L’oubli de refermer un fichier. Cette considération est particulièrement importante lors des accès à un fichier partagé sur un serveur. La valeur zéro retournée par IOresult indique que tout c'est bien passé.3 Fermeture d’un fichier En fin d’utilisation un fichier doit être fermé pour une purge éventuelle du tampon interne . Fichier = ‘essai. Si une erreur survient. En Turbo Pascal. texte ou sans type ). Les procédures à utiliser pour l’ouverture d’un fichier se nomment Reset. Sinon vous auriez rapidement trop de fichiers ouverts à la fois ( 20 tampons peuvent être ouvert simultanément sous MsDos ). Il ne faut jamais préjuger qu’une information est immédiatement déposée sur le disque aussitôt après une opération d’écriture. écriture ou les deux ) l’exploitation du tampon sera différente. 4. Repertoire + ’\’ + Fichier ) . c'est une erreur que de transférer un fichier qui a été ouvert en écriture à une procédure orientée en entrée ( Read ou Readln ). le tampon d’échange. le programme se termine en affichant un message d'erreur à l'exécution ( Run-time error ). Cette particularité permet de tenter sans risque plusieurs opérations disques en séquence et de ne tester qu’une fois à la fin si tout s'est bien passé.2. Ce n’est qu’après cette opération que l’on peut être assuré que toutes les opérations d’écriture sont physiquement réalisées sur le disque.. Lorsque le contrôle d'entrées-sorties est désactivé.. mais suspend toute autre opération d'entrée-sortie jusqu'à ce que la fonction standard IOresult soit appelée. une erreur d'entrée-sortie ne cause pas l'arrêt du programme. La Les fichiers .2. Rewrite et Append.. Les accès disque effectifs se font via ce tampon à la discrétion du système d’exploitation. Remarquez qu'il est nécessaire de fermer un fichier même si vous n'avez fait que des opérations de lecture. Ce contrôle automatique peut être désactivé et réactivé en utilisant les directives de compilation {$I-} et {$I+}. Assign ( T . Le répertoire du disque est mis à jour pour tenir compte des dernières modifications apportées au fichier. Elles ont un comportement diffèrent selon le type du fichier ( binaire.7 . la condition d'erreur est remise à zéro et les opérations d'entrée-sortie sont effectuées de nouveau.txt’ . il se produit une erreur à l’exécution si l'on referme un fichier qui n'avait pas été ouvert. Nous les détaillerons dans chaque cas dans les sections suivantes. Le fichier disque associé à T est effacé.4 Interventions sur le nom physique d’un fichier Les deux opérations suivantes permettent d’intervenir directement sur le fichier externe associé à une variable fichier interne. Procedure Erase ( Var T : File ) . NouveauNom ) . {$I+} Dans les sections suivantes. Erase ( F ) . 4.signification des divers codes d'erreur est disponible dans l’aide en ligne du Turbo Pascal ( menu Help|Error Messages ). ’c:\tp\travail\essai. Remarque : Le programmeur doit s'assurer que le fichier dénoté par NouveauNom n'existe pas déjà.dat’ ) . Une construction standard est la suivante : Assign ( F . {$I-} Repeat Readln ( N ) Until Ioresult = 0 . {$I+} Procedure Rename ( Var T : File . Si ce fichier est en cours d’utilisation. { si erreur ne rien faire } Assign ( F . Le fichier physique correspondant doit exister sur le disque. il est impératif de le fermer avant de l'effacer. nous utiliserons de nombreuses fois cette technique pour fiabiliser des parties critiques de programmes. Le répertoire du disque est mis à jour pour montrer le nouveau nom du fichier et les opérations ultérieures sur T auront lieu sur le fichier avec ce nouveau nom. A titre d’exemple la séquence suivante ne provoque pas l’arrêt du programme si vous tapez au clavier des caractères non numériques sur le Readln vers la variable entière N : Var N : Integer . If IOresult <> 0 Then Writeln ( ‘impossible d’’effacer le fichier’ ) . Rename ( F . {$I-} Erase ( F ) . Une construction standard est la suivante : Var F : File . If IOresult <> 0 Then . {$I-} Assign ( F . Rename ne doit jamais être utilisé sur un fichier ouvert. NouveauNom ) . If IOresult <> 0 Then Writeln ( ‘nouveau nom invalide ou ancien nom introuvable’ ) . {$I+} Les fichiers - 8 . NouveauNom : String ) . AncienNom ) . Le fichier disque associé à T est renommé en NouveauNom. Close ( T ) . {$I-} Reset ( F ) . Un fichier disque créé par Rewrite ne contient aucune information. sinon il se produira une erreur fatale d'entrée/sortie. {$I+} { si échec alors création } Les fichiers .9 . puis le fichier doit être ouvert par l’une des trois méthodes suivantes : Procedure Rewrite ( Var T : Text ) . c’est-à-dire en mode écriture avec positionnement du pointeur de fichier à la suite de la dernière ligne. End . ’m:vide. Un nouveau fichier disque dont le nom a été préalablement assigné à la variable T est créé et préparé pour le traitement en écriture seule. Append doit être utilisé à la place de Rewrite si l'on désire ajouter une information à la fin d'un fichier texte. {$I+} { création } { puis réouverture en lecture } Procedure Append ( Var T : Text ) . La construction suivante permet de résoudre le problème de l’appel à Append vers un fichier qui n’existerait pas déjà sur le disque : {$I-} Append ( T ) . Le nom du fichier externe correspondant doit exister sur le disque. Reset ( F ) . Le fichier disque dont le nom a été préalablement assigné à la variable T est préparé pour traitement en lecture seule. Le pointeur du fichier est positionné au début de ce fichier. Assign ( F . Par exemple les instructions suivantes créent un fichier de taille zéro sur le disque M: Vous pouvez vérifier ce fait en lisant le catalogue de M: Assign ( T . Le contenu de tout fichier préexistant avec le même nom est détruit. SonNom ) .txt’ ) . If IOresult <> 0 Then Rewrite ( T ) . Rewrite ( T ) .5 Les fichiers textes en Turbo Pascal 5.1 Ouverture et fermeture de fichiers textes Avant de pouvoir être exploitée. Procedure Reset ( Var T : Text ) . une variable fichier interne doit avoir été associée à un fichier externe avec Assign. La construction suivante permet d’éviter ce problème. Ouvre un fichier texte existant en mode ajout. If IOresult <> 0 Then Begin Rewrite ( F ) . Eof est toujours Vrai sur un fichier ouvert avec Rewrite ou Append. Procedure Flush ( Var T : Text ) . la fonction Eof retourne Vrai si le pointeur de fichier est positionné sur la marque de fin de fichier ( le caractère de code 26 ). Si Eof ( T ) est Vrai. Fonction booléenne retournant Vrai si la fin de ligne a été atteinte. mais écarte les espaces. 5. Function Eoln ( Var T : Text ) : Boolean . La variable interne redevient disponible pour une autre association ou une ouverture du même fichier externe dans un autre mode. Flush vide le tampon interne associé au fichier T et assure que ce tampon a été écrit sur le disque. En environnement réseau ou pour des données sensibles. c'est-à-dire si le pointeur de fichier est positionné sur le caractère CR de la séquence CR/LF. Readln ( T ) { passage à la ligne suivante} End . Close est l’unique méthode pour refermer un fichier. La construction suivante permet un traitement global d’un fichier texte ouvert en lecture. Similaire à Eof. Flush ne doit jamais être utilisé sur un fichier fermé et ne referme pas le fichier. Un exemple classique est le suivant où nous lisons le contenu du fichier ligne à ligne. Notez notre choix de la boucle TantQue plutôt que Répéter Jusqu’à qui permet d’éviter un grave problème de lecture impossible si le fichier était initialement vide : While Not Eof ( T ) Do Begin { instructions de lecture d’une information} { instructions de traitement de cette information } End . alors Eoln ( T ) est également Vrai. Appliquée à un fichier texte. Notez l’instruction Readln ( T ) qui permet lorsque Eoln est devenu Vrai de passer à la ligne suivante : While Not Eof ( T ) Do Begin While Not Eoln ( T ) Do Begin {instructions de lecture de la ligne courante} End . Function SeekEof ( Var T : Text ) : Boolean . Les fichiers - 10 .2 Fonctions d'états sur les fichiers textes Function Eof ( Var T : Text ) : Boolean . Flush permet également de s'assurer que la prochaine instruction de lecture effectuera réellement une lecture physique depuis le disque. il est prudent d’appeler régulièrement Flush pour forcer l’écriture physique des dernières modifications. les tabulations ou les lignes vides avant de tester la marque de fin de fichier.Procedure Close ( Var T : Text ) . chaînes.. { en cas d’autre chose ! } { lecture d’un enregistrement disposé sur trois lignes d’un fichier texte } Type tInfo = Record Nom . mercredi .Vn sont des variables de type simple ( caractère. . Par exemple. V1... Les valeurs sont automatiquement converties à partir de ou vers leur représentation binaire sous forme de suite de caractères. mais écarte les espaces et les tabulations avant de faire le test de fin de ligne. jusque et y compris la Les fichiers . à moins que ce type d’erreur ait été désactivé... Age : Integer End . V2 . . Les variables de type booléen. jeudi . 5.. Prenom : String . Readln ou Write. Read permet l'entrée de caractères. Vn ) .. entier. N ). Similaire à Eoln. . L : String . Readln ( T . la codera en binaire et la stockera dans la variable N. Vn ) . Ligne ) . chaîne. Cette instruction lira cette séquence. Age ) End . énumérés ou structurés ne peuvent être lues directement et doivent faire l’objet d’un transcodage ou d’une décomposition en type simple comme dans les exemples suivants : { lecture d’un type énuméré depuis un fichier texte } Type tJour = ( lundi ... dimanche .. erreur ) . Var V1 . vendredi . le reste de la ligne est ignoré. If Ligne = ‘lundi’ Then J := lundi Else If Ligne = ‘mardi’ Then J := mardi Else . Tous les caractères. excepté que lorsque la dernière variable a été lue. V2 .. espère trouver à la position courante du fichier texte une séquence de chiffres représentant un nombre entier.. Var V1 .. Prenom ) .. Readln ( T . mardi . Var Fiche : tInfo .. et de données numériques. Readln ( T . Tout caractère illégal provoquera une erreur à l’exécution. N étant une variable entière. . Writeln exactement comme pour les entrées-sorties au clavier et à l'écran. Procedure Read ( Var T : Text . Read ( F. La procédure Readln est identique à la procédure Read. With Fiche Do Begin Readln ( T .3 Entrée et sortie de textes Les fichiers texte utilisent les primitives Read. Var J : tJour .. V2.Function SeekEoln ( Var T : Text ) : Boolean ... . Procedure Readln ( Var T : Text .. Nom ) . { les autres cas possibles de mercredi à dimanche } Else J := erreur .. ou réel ).11 . samedi .. Tous les caractères présents sont significatifs. Avec une variable du type String : Read lit autant de caractères que permis par la déclaration de la longueur de la chaîne.. Nom ) . Eoln devient Vrai si le caractère suivant est un retour chariot ou la marque de fin de fichier. . Avec une variable de type Char : Read lit un caractère dans le fichier et affecte ce caractère à cette variable. Les fichiers - 12 . Notez l’utilisation de la Function Trim. Dans ce cas. à moins que Eoln ou Eof soient rencontrés avant. Var Nom . Après une instruction Readln. Une autre solution serait de lire le fichier un caractère à la fois et de reconstituer les chaînes nom et prénom en utilisant le premier espace comme indicateur de séparation entre les deux. Prenom . sont écartés.. Readln peut également être appelée sans paramètre. Eof devient Vrai si le caractère suivant est une marque de fin de fichier ou une fin de fichier physique. Eof devient Vrai si le caractère suivant est une marque de fin de fichier ou une fin de fichier physique. Nom := Trim ( Nom ) . Par exemple si un fichier contient les informations suivantes : Un prénom sur les 20 premières colonnes de chaque ligne Un nom sur les 20 colonnes suivantes {0 1 2 3 4 5} {12345678901234567890123456789012345678901234567890} BERNARD ALAIN MICHEL DUPONT DURAND DUBOIS Il faudra lire ce fichier en déclarant deux variables Prénom et Nom exactement dimensionnées comme des String [ 20 ] comme suit.prochaine séquence CR/LF. Nom ) End . Eoln devient Vrai si le caractère suivant est un retour chariot ou un la marque de fin de fichier. Si un fichier texte contient plusieurs informations de type textuel par ligne. de l’unité Chaînes qui permet de supprimer les espaces situés à la fin du Prénom et du Nom qui ont aussi été lus dans le fichier : Uses Chaines . Prenom : String [ 20 ] . Prenom := Trim ( Prenom ) .... y compris les espaces ou les tabulations. le reste de la ligne est ignoré. While Not Eof ( T ) Do Begin Readln ( T . une opération Read ou Readln lira au début de la ligne suivante. Traiter ( Prenom . il est donc capital de dimensionner correctement les chaînes des caractères qui recevront les valeurs lors de la lecture. P := Pos ( ‘ ‘ . Ligne ) .Uses Chaines . il est beaucoup plus simple de créer un fichier texte avec une information par ligne. ce qui permettra de le relire ultérieurement par une simple série de Readln. While Not Eoln ( T ) Do Begin Read ( T . While Not Eof ( T ) Do Begin Readln ( T . C ) . 1 . Avec une variable numérique ( entier ou réel ) : Read attend une chaîne de caractères se conformant au format d'une constante numérique du type adéquat. les retours chariots ou les fins de ligne précédant la chaîne sont écartés. et elle doit être suivie par un espace. Nom := Nom + C End . un retour chariot. Les fonctions Pos. ou une marque de fin de fichier. 1 .. Copy et Delete sont des opérations standard du Turbo Pascal. Nom := Trim ( Ligne ) End .. While Not Eof ( T ) Do Begin Nom := ‘’ . { lecture du prénom } { ignorer espaces avant le nom} { lecture du nom } { ligne suivante } Une solution plus simple serait de lire le fichier ligne à ligne dans une chaîne de caractères et de décomposer ensuite cette ligne en un Prénom et un Nom en recherchant le premier caractère espace.. . C ) . Prenom := ‘’ . C ) . une tabulation.1 ) . Prenom := Prenom + C End . Delete ( Ligne . C := ‘*’ . Ligne ) . Nom := Trim ( Nom ) . While ( C <> ‘ ‘ ) Do Begin Read ( T . et si l’on a le choix. P ) . Var C : Char . ( voir l’aide en ligne ). While C = ‘ ‘ Do Read ( T . En conclusion. Prenom := Copy ( Ligne . Var Ligne : String . Les fichiers . P . Tous les espaces. La chaîne ne doit pas avoir plus de 30 caractères. Readln ( T ) End . les tabulations.13 . suivies éventuellement du signe ':' et d'une expression entière définissant la longueur du champ de sortie ( paramètres d’écriture ). A . V2 . . D ) . Write ( T . m. . Var V1 . justifié a droite dans un champ de n caractères. Ch représente une expression caractère. nous utilisons les symboles suivants : l. Eoln est Vrai si la chaîne est suivie d’un retour chariot ou d’une fin de fichier. S ) La chaîne S est sortie. C . S est précédée par n . V1. D ) End . il se produit une erreur d'entrée/sortie. chaînes.Length ( S ) espaces. Cas particulier : Si Eoln ou Eof est Vrai au début de l'opération Read ( si on lit seulement un retour chariot sur le clavier ). D déclarées comme des entiers ) : While Not Eof ( T ) Do Begin Readln ( T .1 espaces. et Eof est Vrai si la chaîne est terminée par une fin de fichier. Write ( T .Si la chaîne ne se conforme pas au format attendu. S représente une expression chaîne.. justifiée à droite dans un champ de n caractères. B. R représente une expression réelle. justifiée à droite dans un champ de n caractères. Write ( T . Write ( T . Vn ) . V2. séparés par des tabulations ( ou des espaces ) comme celui-ci : 1 2 5 6 9 10 . Write ( T . c'est-àdire que Ch est précédé par n .. I ) La représentation décimale de la valeur I est sortie.. 3 4 7 8 11 12 devrait être lu par la séquence suivante ( avec A. C. R ) La représentation de la valeur de R est sortie en notation scientifique. Les fichiers - 14 . et valeurs numériques. n représentent une expression entière. Ch:n ) Le caractère Ch est sorti. Write ( T . la chaîne numérique est convertie en une valeur du type approprié qui est affectée à la variable. Procedure Write ( Var T : Text . S:n ) La chaîne S est sortie. Dans les descriptions suivantes des différents formats et de leurs effets. Vn sont des variables du type simple.. valeurs booléennes. Le format d'un paramètre d'écriture dépend du type de la variable. Traiter ( A . C . B . aucune valeur n'est affectée à la variable qui reste inchangée. I:n ) La représentation décimale de la valeur de I est sortie. Par exemple un fichier qui contiendrait quatre nombres entiers par ligne. Dans le cas contraire. . Ch ) Le caractère Ch est sorti. La procédure Write permet la sortie de variables de type simple comme les caractères.. B .. Write ( T . 2 : quel serait l'aspect du fichier NB10A20.1 : quel sera l'aspect du fichier NB10A20. justifiée à droite dans un champ de n caractères.15 . en utilisant la notation en virgule flottante avec m chiffres après le point décimal. I:4 ) ? exercice 6. R:n:m ) La représentation décimale de la valeur de R est sortie. Le nombre est précédé par un nombre d'espaces approprié pour remplir un champ de n caractères. .. Begin Assign ( T . justifiée à droite dans un champ de n caractères. Write ( T . I ) par Write ( T . vous pouvez le relire avec n'importe quel traitement de texte et éventuellement le modifier. I ) ou par Write ( T . { ouverture en écriture } For I := 10 To 20 Do Writeln ( T . en n'oubliant pas de spécifier l'extension ( TXT ). I ) . Program CreeFichierDeNombres . V2 . { accès en écriture} Close ( T ) { fermeture} End . La procédure Writeln est identique à la procédure Write.TXT si on omettait l'instruction Close ? Nous pouvons aussi le relire par un programme Pascal symétrique.TXT' ) . 'NB10A20. Procedure Writeln ( Var T : Text . Si m est égal à zéro. puisque nous avions déposé un nombre par ligne. Var V1 . 20 exercice 6.Write ( T . qui ouvre le fichier en lecture. .. 6 Manipulations simples de fichiers textes Le programme suivant crée un fichier texte contenant les nombres de 10 à 20 à raison de un par ligne. et les affiche à l'écran : Les fichiers . soit onze lignes. il n'y a pas de partie décimale ni de point sortis. Vn ) .TXT si on remplace le Writeln ( T . Pour en voir le contenu il suffit de l'ouvrir avec Turbo Pascal. en utilisant la notation en virgule flottante. Puisque le fichier ainsi créé est un texte. . . avec l'émission d'une séquence CR/LF après la dernière valeur. Vous devriez voir apparaître dans une nouvelle fenêtre : 10 11 12 . I : Integer . puis relit chaque nombre par des Readln. R:n ) La représentation décimale de la valeur de R est sortie. Rewrite ( T ) . Var T : Text . Une instruction Writeln sans paramètres d'écriture écrit seulement une ligne vide ou termine la ligne en cours. S'il en a moins. 'NB10A20. Pourquoi ? Assign ( T . Close ( T ) . Writeln ( I ) End . N ) . 'NB10A20.TXT s'il avait été fabriqué avec Write ( T . Begin Assign ( T . { ouverture en lecture seule } { lecture d'un nombre } { et affichage } { fermeture } { pour avoir le temps de voir le résultat ! } exercice 6. Close ( T ) . il s’arrêtera avec une erreur fatale d'entrée-sortie ( lecture au-delà de la fin d'un fichier ) et s'il y en plus. I : Integer .TXT' ) . exercice 6. Reset ( T ) . Begin Assign ( T . For I := 1 To 11 Do Begin Readln ( F . 'NB10A20. I:4 ) ? Un des gros avantages des fichiers textes est qu'ils peuvent toujours être considérés comme des fichiers de caractères.TXT ne contient pas exactement 11 nombres. Var T : Text . N : Integer . I ) ou Write ( T . Pour les relire il suffit donc d'en extraire l'information un caractère à la fois comme le montre l'exemple suivant.Program RelitFichierDeNombres . Close ( T ) . While Not Eof ( T ) Do Begin Readln ( T . Var T : Text . For I := 1 To 11 Do Begin Readln ( T .4 : comment relire le fichier NB10A20. quelle que soit sa taille grâce à l'utilisation de la fonction Eof : Program RelitFichierDeNombres . I . Le programme précédent risque de poser problème si le fichier NB10A20. Nous lui préférerons donc la version suivante qui affiche l'ensemble du fichier. Reset ( T ) . I ) . Reset ( T ) . Readln End . Writeln ( I ) End .3 : le programme suivant n'affiche pas correctement les 11 nombres.TXT' ) .TXT' ) . il n'affichera que les onze premiers. Writeln ( N ) End . I ) . Remarquez l'utilisation de Read qui lit exactement la quantité Les fichiers - 16 . Readln End . 5 : écrire un programme qui affiche le nombre de lignes d'un fichier texte. par une série de Readln vers une variable de type chaîne de caractères.d'information spécifiée par le type de son paramètre ( ici un caractère ) et non pas de Readln qui chercherait à changer de ligne entre chaque caractère du fichier. Close ( T ) . Ligne : String . Il importe seulement qu'aucune ligne ne soit plus longue que la taille maximale permise par un type String.17 . Assign ( T . Readln End . Begin Write ( 'nom du fichier à lire : ' ) .7 : écrire un programme qui affiche le nombre de chiffres et de lettres contenu dans un fichier texte. I . Si le fichier est organisé en lignes. Nom ) . Program RelitToutFichierTexte .6 : écrire un programme qui affiche le nombre de mots d'un fichier texte. Write ( C ) End . N : Integer . Writeln ( Ligne ) End . C ) . Nom : String . exercice 6. While Not Eof ( T ) Do Begin Read ( T . Nom ) . Begin Write ( 'nom du fichier à lire : ' ) . Readln ( Nom ) . Var T : Text . C : Char . Readln End . d'abord en admettant que chaque ligne a une longueur inférieure à 256 caractères puis en levant cette restriction. soit 256 caractères. Ligne ) . While Not Eof ( T ) Do Begin Readln ( T . Program RelitToutFichierTexteAvecDesLignespasTropLongues . Les fichiers . d'abord en admettant que chaque ligne a une longueur inférieure à 256 caractères puis en levant cette restriction. exercice 6. Reset ( T ) . exercice 6. on peut aussi le relire une ligne à la fois. Nom . Var T : Text . Readln ( Nom ) . Close ( T ) . Reset ( T ) . Assign ( T . nous allons utiliser les procédures utilitaires cidessous : procedure OuvreEnLecture ( Var F : Text .exercice 6. Ouvre le fichier texte F en écriture. . .on ouvre en écriture le fichier temporaire. Pour tester ce programme. Afin de simplifier l'écriture de ces algorithmes..on poursuit la recopie du fichier originel vers le fichier temporaire jusqu’à sa fin. SonNom : String ) . . procedure DuplicFichier ( NomOriginel . Duplique le contenu du fichier disque dont le nom est NomOriginel vers celui dont le nom est NomFinal et supprime du disque le fichier NomOriginel. Il vous faut deux lecteurs de cassettes. .écriture d'une autre valeur en cas de modification. un pour lire et l'autre pour enregistrer et à la fin vous mettez à jour les étiquettes sur les bandes. Les fichiers - 18 .écriture d'une nouvelle information en cas d'ajout. le fichier disque qui a le nom utilisé par le programme contient toujours l'ancienne version de l'information. On utilisera une fonction CarMajuscule ( C : Char ) : Char qui convertit en majuscule un caractère si nécessaire et le renvoie inchangé sinon. ce qui aura pour effet de le créer s'il n'existe pas ou d'en détruire un contenu précédent.soit recopier le fichier temporaire dans le fichier originel et supprimer le fichier temporaire.8 : écrire un programme qui affiche le numéro de chacune des 26 lettres de l'alphabet contenu dans un fichier texte. il vous suffira d'utiliser l'unité Chaînes disponible sur le serveur qui exporte cette fonction. . un fichier texte ne peut pas être ouvert simultanément en lecture et en écriture. et encore moins d'y insérer ou d'y supprimer une information. C'est le fichier dont le nom est celui choisi pour le fichier temporaire qui contient la bonne version. Et ce n'est pas fini ! A la fin de cette opération. Toute intervention sur un fichier texte nécessite donc l'utilisation d'un second fichier texte temporaire selon la méthode générale suivante : . Il faut donc : . puis que l'on écrive à cet endroit précis. NomFinal : String ) . cette méthode doit vous êtres familière. .pas d'action pour une suppression. .on réalise l'intervention sur le fichier temporaire comme suit : .soit “ échanger ” les noms sur le disque par une utilisation judicieuse des primitives Rename et Erase vues ci-dessus. en l'associant au fichier physique SonNom.on recopie le fichier originel dans le fichier temporaire jusqu'à ce que l'on ait atteint l'information visée.. et enfin que l'on continue à lire la suite du fichier. SonNom : String ) . Faire disparaître du disque le fichier de nom SonNom. . Procedure SupprimeFichier ( SonNom : String ). En effet ces opérations nécessitent que l'on lise le contenu du fichier jusqu'à l'information voulue. 7 Modification du contenu d'un fichier texte Comme nous l'avons déjà signalé.. procedure OuvreEnEcriture ( Var F : Text . en l'associant au fichier physique SonNom.on ouvre en lecture le fichier originel. L'appel à Reset interdit l'utilisation des primitives de type Write et l'appel à Rewrite commence par détruire le contenu du fichier ! Il est donc impossible de modifier le contenu d'un fichier texte en écrivant la nouvelle valeur d'une information par dessus l'ancienne. Si vous avez déjà réalisé des insertions de morceaux de musique au beau milieu de cassettes audio. Ouvre le fichier texte F en lecture. C : Char . Begin Assign ( F . G : Text . Begin OuvreEnLecture ( F . Begin Assign ( F . NomFinal ) . NomFinal : String ) . Procedure SupprimeFichier ( SonNom : String ) .19 . C ) End . voici la procédure d'ajout d'un nouveau nombre à la fin de ce fichier. SonNom ) . While Not Eof ( F ) Do Begin Read ( F . Var F : Text . OuvreEnEcriture ( G . Begin Assign ( F . SonNom ) . NomOriginel ) . Notez le choix d'un nom suffisamment exotique pour le fichier temporaire afin de ne pas détruire un fichier qui existerait sur le disque. Close ( F ) . Procedure OuvreEnEcriture ( Var F : Text .Le code de chacune de ces procédures est fort simple.. Procedure DuplicFichier ( NomOriginel . SonNom : String ) . Rewrite ( F ) End . Write ( G . Close ( G ) . Procedure OuvreEnLecture ( Var F : Text . avec un nombre par ligne. Reset ( F ) End . En reprenant l'exemple du fichier de nombres. Var F. SonNom : String ) .. Erase ( F ) End . SupprimeFichier ( NomOriginel ) End . SonNom ) . Les fichiers . C ) . OuvreEnEcriture ( Tempo . sauf les nombres qui seraient trouvés égaux à celui que l'on cherche à éliminer. exercice 7. qui permet d'ouvrir un fichier texte existant en écriture sans le détruire et de se positionner directement à la fin.4 : sur le modèle précédent écrire une procédure AjouteAvant qui insère un nouveau nombre avant un autre nombre ( passés en paramètre ) contenu un fichier texte.2 : sur le modèle précédent écrire une procédure AjouteEntete qui insère un nouveau nombre passé en paramètre au début d'un fichier texte. exercice 7. Tempo : Text .$$$' ) . X : Integer . NomFichier ) { recopie du temporaire { vers l'original et destruction } { du fichier temporaire } End . While Not Eof ( F ) Do {recopie d'abord tout le fichier original } Begin Readln ( F . Exploiter cette primitive pour obtenir une version plus simple de AjouteEnfin.3 : sur le modèle précédent écrire une procédure AjouteApres qui insère un nouveau nombre après un autre nombre ( passés en paramètre ) contenu dans un fichier texte. exercice 7. Var F .Procedure AjouteEnFin ( NomFichier : String . 'ABC. { puis écrit le nouveau nombre à la suite} Close ( F ) . X ) { dans le fichier temporaire} End . Writeln ( Tempo . exercice 7. Close ( Tempo ) . UnNombre ) .$$$' . Writeln ( Tempo . Il faut recopier l'originel dans le temporaire. Les fichiers - 20 . DuplicFichier ( 'ABC. exercice 7. X ) . UnNombre : Integer ) .5 : comment se comportent les deux procédures précédentes si le nombre après ou avant lequel il faut ajouter le nouveau existe plusieurs fois dans le fichier texte ? Comment résoudre ce problème ? La suppression d'une information de notre fichier de nombres est très similaire.1 : le Turbo Pascal possède une primitive non standard nommée Append. Notez le paramètre supplémentaire Ok qui vaudra Vrai en sortie si l'on a réalisé au moins une suppression. NomFichier ) . Begin OuvreEnLecture ( F . 21 . Var Ok : Boolean ) . Ok := False . NomFichier ) . Close ( F ) . 'ABC. Quelle est son temps d’exécution par rapport à la version ci-dessus ? exercice 7. { supprime toutes les occurrences de UnNombre } Var F . car il n'est pas possible d’affecter à un fichier un nom qui existerait déjà sur le disque.TXT. NomFichier ) End . mais simplement d'échanger leurs noms sur le disque. Procedure DuplicFichier ( NomOriginel .7 : de façon analogue écrire des procédures nommées RemplaceNieme et RemplaceTout qui remplacent la Nieme occurrence ou toutes les occurrences d'un certain nombre par une nouvelle valeur dans un fichier texte. D'ou la version suivante où l'on commence par supprimer du disque le fichier ayant le nom NomFinal ( 'NB10A20. DuplicFichier ( 'ABC. Rename ( F . OuvreEnEcriture ( Tempo . Bien sûr cette procédure ne doit être appelée que dans un contexte où le nom spécifié par NomOriginel existe bien sur le disque. Close ( Tempo ) . écrire une procédure nommée SupprimeNieme qui supprime la Nieme occurrence d'un certain nombre d'un fichier texte. Begin OuvreEnLecture ( F . exercice 7. NomFinal ) End . NomOriginel représente le nom 'ABC. While Not Eof ( F ) Do { tant que l'on a pas atteint la fin du fichier } Begin Readln ( F . Begin Assign ( F .$$$' ) .TXT' ) puis on renomme le fichier ABC. Une version plus subtile de DuplicFichier serait de ne pas recopier les contenus des fichiers. X ) . ce qui est notre cas.$$$' et NomFinal 'NB10A20.Procedure SupprimeTout ( NomFichier : String . UnNombre : Integer . { fausse } Var F : Text . En déduire une nouvelle version de SupprimeTout. Tempo: Text . NomFinal : String ) . NomOriginel ) . X ) { de celui à supprimer } Else Ok := True { on l'a trouvé. X : Integer . If X <> UnNombre Then { on ne recopie que les nombres différents } Writeln ( Tempo . donc on ne recopie pas et } { on indique le succès } End . Dans ce contexte d'appel. Les fichiers .6 : sur le modèle ci-dessus. L'idée d'utiliser directement la procédure Rename du Turbo Pascal ne fonctionne pas.$$$ en NB10A20.TXT' et ces deux fichiers existent réellement sur le disque.$$$' . Begin Assign ( F . Assign ( F . Si nous avions fabriqué un fichier texte avec un nom. un prénom et une note par ligne. If IoResult <> 0 Then { si il y a eu erreur tant pis } {$I+} { retour à la normale } End . NomFinal ) End . NomFinal : String ) . Les valeurs à placer dans les différentes colonnes de chaque ligne Excel doivent être séparées par une tabulation ( le caractère de code ASCII 9 ). il est possible de le récupérer directement avec Excel comme le montre la boîte de dialogue Ouvrir cidessous : Les fichiers - 22 . NomFinal ) . Procedure DuplicFichier ( NomOriginel . Rename ( F . Var F : Text . Une version beaucoup plus générale est la suivante.Procedure DuplicFichier ( NomOriginel . NomFinal ) . Par exemple. NomFinal ) . l’intérêt majeur des fichiers textes est de permettre l’échange d’informations entre des programmes différents. {$I-} { pas d'arret sur erreur } Erase ( F ) . NomOriginel ) . Begin Assign ( F . NomFinal : String ) . Rename ( F . Pour renommer un fichier en un autre il faut essayer de supprimer le nouveau nom du disque. Erase ( F ) . Var F : Text . NomOriginel ) . If IoResult <> 0 Then . le logiciel tableur Excel est capable de relire directement le contenu d'un fichier texte organisé en lignes. ignorer l'erreur s'il n'existait pas et réaliser enfin le renommage. au cas où il existerait. 8 Les fichiers textes pour l'échange de données Comme nous l’avons déjà signalé. { si il y a eu erreur tant pis } Assign ( F . etc.Les données peuvent alors être traitées sous Excel ( triées. harmonisées.23 . ). Excel peut enfin enregistrer de nouveau cette feuille de calcul modifiée au format texte avec divers séparateurs comme le montre la boîte de dialogue Enregistrer sous ci-dessous : Les fichiers . 'LPT1:' ) . Rewrite ( Sortie ) . moyenne et écart-type de ces notes.. 'Hello la planète. Relire le fichier avec Excel et calculer la somme. Close ( Sortie ) Les fichiers - 24 ..' ) . Relire ce fichier avec un programme Pascal qui affichera les nom. l'écran et l'imprimante comme des périphériques. En réalité. Par exemple. Writeln ( Sortie . Var Sortie : Text . Begin Assign ( Sortie . 9 Périphériques dans Turbo Pascal Turbo Pascal et le système d'exploitation MsDos considèrent les équipements externes tels que le clavier.. exercice 8. un prénom et une note. une colonne de prénoms et une colonne de notes. Turbo Pascal n'a pas conscience du fait qu'une variable fichier se réfère à un périphérique plutôt qu'à un fichier sur disque.1 : écrire un programme en Turbo Pascal qui crée un fichier texte contenant sur chaque ligne un nom. bien que la syntaxe utilisée soit exactement la même que pour un fichier sur disque. Du point de vue du programmeur. le programme écrira la chaîne de caractères 'Hello la planète.. nous obtiendrons le contenu suivant : nom prénom note dubois roger durand michel dupont rené duval pierre martin paul 8 4 12 14 10 exercice 8.' sur l'imprimante. Les périphériques MsDos sont implémentés grâce à des noms de fichiers réservés ayant une signification particulière. un périphérique est traité comme un fichier texte et les opérations sont exécutées avec les mêmes procédures et fonctions.2 : créer avec Excel un fichier texte contenant une colonne de noms.Pour notre fichier. prénom et note et calculera la moyenne des notes. End . il suffit d’associer InputOutput au périphérique sans nom pour que toutes les entrées-sorties écran-clavier s’adressent aux fichiers redirigés.PAS ) vous demande votre nom et vous salue. Input et Output sont automatiquement refermés à la fin du programme. De la même manière. Si vous le lancer par REDIR > BONJOUR. Pour la première imprimante. Dans le cas de redirection des entrées-sorties au niveau de MsDos. Rewrite ( Output ) . tous les ordres Writeln se feront vers un fichier texte BONJOUR.TXT . Begin { prise en compte d’une éventuelle rédirection par MsDos } Assign ( Output . LPT2 et LPT3 La famille de périphériques LPTx concerne les trois imprimantes que vous pouvez utiliser sur votre système. Close ( Input ) End . Tous les ordres Read et Write sans paramètres indiquant le nom du fichier se réfèrent à ce périphérique. ) ou Writeln ( Lst .TXT . Program Redirection . Si vous le lancer par REDIR > BONJOUR. Les fichiers . qui permet d'envoyer des informations vers l'écran et d'en recevoir à partir du clavier. Pour facilement écrire quelque chose sur l'imprimante depuis l'un de vos programmes. Readln ( Nom ) . vous pouvez utiliser le synonyme PRN. Si vous le lancer par REDIR. Var Nom : String .TXT < MOI. Lorsque les entrées et les sorties ne sont pas redirigées. Par exemple. Input et Output sont automatiquement ouverts au début du programme.. vous répondrez au clavier et le salut s’affichera à l’écran.25 . Close ( Output ) .TXT. Les fichiers standard Input et Output et tous les fichiers assignés à un nom de fichier vide se référent implicitement à ce périphérique. Reset ( Input ) . par contre vous devrez taper au clavier votre nom.TXT. Writeln ( ‘votre nom ‘ ) . Les périphériques LPT1. . il cherchera à lire votre nom dans le fichier MOI. Nom ) . '' ) .. Writeln ( ‘ Bonjour ’ . ). '' ) . . il vous suffit d'inclure l'unité Printer dans la clause Uses du programme et d'utiliser Write ( Lst . Note : l'unité standard Printer contient la déclaration d'une variable de fichier texte appelée Lst qu'elle associe au périphérique LPT1.. Assign ( Input .. vous verrez apparaître à l’écran la question. le programme suivant ( REDIR.TXT puis déposera la réponse dans le fichier BONJOUR. Nous donnons ci-dessous la liste des périphériques MSDOS les plus connus : Le périphérique sans nom Ce périphérique correspond à la console. Le synonyme AUX peut être utilisé pour COM1. Close ( Sortie ) .TXT’ ) { un vrai fichier texte} End . End . 'PRODUITS. Les fichiers - 26 .Les périphériques COM1 et COM2 Les périphériques de communication concernent les deux ports de communication série. CodeFourni : Integer . Quantite : Real . { tampon de lecture } Sortie : Text . ’i’ : Assign ( Sortie . Type { déclarations articles du fichier binaire } tProduit = Record Nom : String [ 80 ] . Nom:20 . Quantite:20:2 . Program ListProducFile . alors que le programme désire tout de même une entrée ou une sortie d'information. ’’ ) .DAT vers l’écran. Ce périphérique est peu exploitable tel quel car MsDos gère très mal la communication à travers les ports série. { le fichier binaire} Produit : tProduit . Reset ( FicProduits ) . While Not Eof ( FicProduits ) Do Begin Read ( FicProduits . Writeln ( ‘sortie vers Ecran Imprimante Fichier (E I F )’) . { le fichier texte de sortie} Rep : Char . ’PRN’ ) . ’e’ : Assign ( Sortie . Var FicProduits : File Of tProduit . Case Rep Of ‘E’ . End . l’imprimante ou un véritable fichier texte ( PRODUITS. ’Code Fournisseur’:10 ) . Writeln ( Sortie . ’Code Produit’:10 . ’F’ ] . Produit ) . Vous l'utiliserez lorsque vous ne voudrez pas créer de fichier particulier. ’f’ : Assign ( Sortie . Le périphérique NUL Ce périphérique ignore toute écriture et génère une fin de fichier immédiate lorsque vous essayez d'en lire le contenu. CodeProduit : Integer . { PRN : nom de l’imprimante} ‘F’ . ’I’ . Close ( FicProduits ) .DAT' ) . ’PRODUITS. { vers l’écran fichier anonyme} ‘I’ . Begin Assign ( FicProduits .TXT ). Repeat Readln ( Rep ) Until Upcase ( Rep ) In [ ‘E’ . With Produit Do Writeln ( Sortie . Le programme suivant montre l'emploi des périphériques pour sortir à volonté le contenu d'un fichier typé nommé PRODUITS. CodeFourni:10 ) End . ’Quantité’:20 . ’Nom ‘:20 . Rewrite ( Sortie ) . CodeProduit:10 . 10. La valeur de cet indice. puis être ouverte par Reset ou Rewrite. {$I+} { création } L’appel à Close reste l’unique méthode pour refermer un fichier. La première fois. qui reste la seule méthode pour créer un fichier vide.27 . le fichier doit être créé avec un appel à Rewrite. S’il y a eu une erreur. Il est regrettable que Turbo Pascal n’ait pas une procédure spécifique d’ouverture d’un fichier binaire avec création automatique si nécessaire. SonNom ) . Chaque fiche est repérée par un indice variant de 0 à la taille du fichier moins 1. nous nommerons fiche une composante. Notez que les procédures Reset et Rewrite ont un comportement identique à celles des fichiers textes mais que dans les deux cas le fichier sera ouvert en lecture et écriture.1 ( environ 2 milliards ) puisque l’indice ne peut être négatif. Pour la remplacer il faut refermer le fichier et le ré-ouvrir de nouveau par : Close ( F ) . un fichier binaire peut être considéré comme un “ tableau hors mémoire ” de composantes de même type. Un problème sérieux est celui de la création du fichier lors de la première exécution d’un programme.2 Fonctions d'états sur les fichiers binaires De façon interne. {$I-} Reset ( F ) . La variable interne redevient disponible pour une autre association ou une ouverture du même fichier externe dans un autre mode. nommé le pointeur de fichier est privée au type File et ne peut pas être manipulée directement. Par analogie avec une simple boîte à fiches. If IOresult <> 0 Then Rewrite ( F ) . Le type de cet indice est Longint ( entier long codé sur 32 bits ) soit une valeur maximale de 231 . On désactive les erreurs d’entrée-sortie. Comment un programme peut-il “ savoir ” si c’est la première fois qu’il est utilisé ? La méthode standard est la suivante. Les fichiers .10 Les fichiers binaires en Turbo Pascal 10. une variable fichier binaire doit avoir été associée à un fichier externe avec Assign. cette opération remet le pointeur de fichier au début du fait de l’appel à Reset. La procédure Flush qui permettait de forcer une écriture physique du tampon vers le disque n’existe plus avec les fichiers binaires. puis on essaie d’utiliser Reset. Reset ( F ) A la différence de Flush. La procédure Append n’est pas permise avec ce type de fichier. Par contre. Un appel à Reset conduirait à une erreur d’exécution puisque le fichier n’existe pas encore sur le disque.1 Ouverture et fermeture des fichiers binaires Tout comme avec les fichiers textes. dés la seconde exécution il faut impérativement faire appel à Reset pour ouvrir simplement le fichier sans en détruire le contenu qui aurait été déposé à l’exécution précédente. c’est que le fichier n’existait pas et on le crée avec Rewrite : Assign ( F . C’est à dire si FileSize est égal à FilePos. La construction suivante permet un traitement global d’un fichier binaire ouvert. Donc l’instruction Seek ( F . While Not Eof ( F ) Do Begin { instructions de lecture d’une information} { instructions de traitement de cette information } End . La position de la première fiche est 0. Les fichiers - 28 .. Function Eof ( Var F : File ) : Boolean . On le manipule à travers une série de procédures et fonctions comme : Function FilePos ( Var F : File ) : Longint .. . Var F : File Of Integer . Appliquée à un fichier binaire. Writeln ( FileSize ( F ) * 2 ) ) . Function FileSize ( Var F : File ) : Longint . Seek déplace le pointeur de fichier sur la Nieme fiche du fichier référencé par F.A chaque opération de lecture ou d’écriture la valeur du pointeur de fichier est automatiquement incrémentée. FileSize ( F ) ) . A cet endroit il n’est possible que d’écrire puisque l’on se trouve au-delà de la fin physique du fichier. le nombre retourné est le rang du dernier composant plus 1. Si FileSize est égale à 0 le fichier est vide. 0 ) permet de se replacer au début du fichier. Eof reste toujours Vrai sur un fichier ouvert avec Rewrite. On utilise la construction suivante : Seek ( F . Fonction entière retournant la taille d'un fichier disque exprimée en nombre de fiches. 0 ) . Notez notre choix de la boucle TantQue plutôt que Répéter Jusqu’à qui permet d’éviter un grave problème de lecture impossible si le fichier était initialement vide : Seek ( F . N : Longint ) . N est une expression entière de type entier long ( Longint )... Write ( ‘taille du fichier en octets égale = ‘ ) . Avec un fichier qui vient d’être ouvert la valeur est zéro. Pour retrouver la taille exacte en octets d’un fichier ( comme affichée par le catalogue de la disquette ) il faut donc multiplier FileSize ( F ) par la taille en octets de chaque fiche obtenue à partir de sa déclaration de type composante ou grâce à la fonction standard Sizeof.. Elle correspond donc à la valeur maximale que l’on peut affecter au pointeur de fichier. ou mieux Writeln ( FileSize ( F ) * Sizeof ( Integer ) ) . Fonction entière retournant la valeur actuelle du pointeur de fichier. FileSize retourne le nombre de fiches d'un fichier et comme les éléments commencent au numéro 0. la fonction Eof retourne Vrai si le pointeur de fichier est positionné après la dernière composante d’un fichier. Pour pouvoir agrandir un fichier on doit déplacer le pointeur juste après la dernière fiche et écrire à cet endroit. Procedure Seek ( Var F : File . Nous préférons cette construction à la suivante qui est équivalente.. Truncate ( F ) Celle-ci détruit l’ensemble du contenu d’un fichier. FileSize ( F ) . I ) . Procedure Read ( Var F : File . Truncate ( F ) 10. Procedure Truncate ( Var F : File ) . . Le type de la variable C doit être exactement identique à celui cité dans la déclaration “ File Of ” de la variable fichier F. Noter qu’il s’agit de l’unique moyen de réduire la taille d’un fichier disque sans le recopier dans un autre.29 .3 Entrée et sortie de composantes Les fichiers binaires utilisent les primitives Read ou Write pour échanger des composantes ( fiches ) entre des variables du type approprié et le fichier physique. Seek ( F . { lire et traiter la composante courante } End .1 Do Begin Seek ( F . La séquence suivante traite l’ensemble des fiches d’un fichier supposé être de type tFiche : Les fichiers . Coupe le fichier à la position courante ( définit cette position en tant que fin du fichier ). La procédure Read permet la lecture de composantes depuis le fichier.. Elle est équivalent à Rewrite ( F ) : Seek ( F . Readln et Writeln ne sont pas autorisés car il n’y a pas de conversion binaire texte dans ce cas.1 ) . mais utilise une variable I supplémentaire : Var I : Longint . 0 ) . La séquence suivante détruit la dernière fiche d’un fichier et réduit donc sa taille sur le disque d’une fois la taille d’une fiche. Var C ) . For I := 0 To FileSize ( F ) . Fiche ) . Puis relire ce fichier comme un File Of LongInt et un File Of Integer. Si vous ignorez le type des fiches. exercice machine 10. Writeln ( Fiche. Fiche : tFiche .Nom ) . 0 ) . Prenom : String [ 10 ] ..3. Read ( F . . La construction suivante sera rejetée par le compilateur avec une erreur de type : Var F : File Of tFiche . il importe qu’il y ait une correspondance exacte entre le type réel des fiches contenues dans un fichier et la déclaration qui en est faite en Pascal. L’exemple suivant affiche les noms inscrits sur toutes les fiches d’un fichier déclaré comme ci-dessus : Seek ( F . 0 ) . Comme nous l’avons déjà signalé. Seek ( F ..{ lecture des enregistrements d’un fichier binaire } Type tFiche = Record Nom . Rien ne vous interdit de créer un fichier avec un certain type de fiche et de le relire ultérieurement avec un autre. While Not Eof ( F ) Do Begin Read ( F . il est impossible d’exploiter le fichier. Si l’on a besoin de consulter le nom d’une personne. Traiter ( Fiche ) End . Notez qu’il n’est pas permis de lire une partie d’une composante. Fiche ) ...1 : créer un fichier binaire contenant une dizaine de nombres réels ( File Of Real ). Age : Integer End . Prenom : String [ 10 ] puis relire ce fichier comme un fichier de type Nom.3. il faut lire l’intégralité de cette fiche dans une variable du type approprié puis en extraire le nom. Var Fiche : tFiche . Fiche.Nom ) End . exercice machine 10. Age : Integer.2 : créer un fichier contenant des fiches de type Nom. soit parce que les valeurs binaires lues n’auront aucun rapport soit parce que vous attendrez inopinément la fin du fichier au beau milieu d’une lecture parce que la taille déclarée de chaque fiche ne correspondra pas à la réalité. . While Not Eof ( F ) Do Begin Read ( F . F : File Of tFiche . Prenom : String . Mais il est plus que probable que le traitement du fichier se passera très mal . Que constatez -vous ? Que faudrait-il faire pour ajouter le champ âge à chaque fiche du fichier ? Les fichiers - 30 . ) leur sont applicables .31 . adresse et code postal ) au début d’un fichier de 10000 adresses. prénom. Toute anomalie de fonctionnement du matériel ou du logiciel le laisserait dans un état irrécupérable. 0 ) . Il est de nouveau interdit d’écrire une partie d’une fiche. While Not Eof ( F ) Do Begin Read ( F . Le type de la variable C doit être exactement identique à celui cité dans la déclaration “ File Of ” de la variable fichier F. Seek ( F . C ) . Ceci est probablement vrai avec de petits fichiers mais certainement pas avec des applications en grandeur réelle. Comme avec Read. C ) .02 ms ( écriture ) soit 240 secondes ( 3 minutes ! ) Les fichiers . modifications. suppressions. La différence majeure est qu’un fichier ne réside pas en mémoire mais sur un disque. C. Avec un disque dur rapide ( temps d'accès 10ms.02ms ( lecture ) + 10000 * 100 * 0. Les algorithmes à utiliser doivent donc travailler une fiche à la fois. se pose dans le cas des fichiers le problème de la capacité disque qu’il convient de surveiller avant de tenter tout agrandissement ou toute recopie d’un fichier. Ces opérations sont longues et dangereuses puisque durant tout le traitement le fichier est ouvert et reste vulnérable. FilePos ( F ) .1 ) . temps d’écriture d’un octet 0. Cette opération nécessite : . il y a avance automatique du pointeur de fichier à la fiche suivante.3.Age := C.Age + 1 . Imaginons l’insertion d’une fiche d’une centaine de caractères (nom. La taille d’un fichier est souvent beaucoup trop importante pour que l’on puisse envisager de le lire en mémoire dans un tableau ( ou une autre structure de données ) pour le traiter avec un algorithme classique puis de réécrire le résultat sur le disque. prénom. en exploitant l’accès direct. FilePos ( F ) . Write ( G . La procédure Write permet d’écrire des fiches à la position courante dans le fichier. End . C ) . au contraire d’un tableau où l’on peut aisément gérer le nombre maximal de composantes. etc.soit. avec d’incessants échanges entre une variable de type tFiche et la composante correspondante du fichier. exercice 10.1 ) dans l’exemple cidessus ? 11 Modifications du contenu de fichiers binaires Le fait que les fichiers binaires soient très similaires à des tableaux pourrait laisser penser que les algorithmes habituels de mise à jour de l’information ( ajouts.02 ms ) ces opérations prendraient 20000 * 10ms ( accès ) + 10000 * 100 * 0.Procedure Write ( Var F : File . le décalage des 10000 fiches d’une position vers le bas c’està-dire 10000 lectures et 10000 écritures. De plus. ces algorithmes sont détaillés dans le chapitre 3 ( Méthodologie de développement ). âge ) du fichier supposé ouvert : Seek ( F .3 : quel est le but de l’instruction Seek ( F . L’exemple suivant ajoute un an à l’âge de toutes les fiches de type ( nom. les fiches sont systématiquement ajoutées à la fin du fichier par la construction suivante: Seek ( F .. Write ( F . ni de décaler d’une place vers le haut les fiches suivantes. Il est possible d’avoir plusieurs tables d'accès et donc plusieurs critères de recherche pour un même fichier ( exemple : le fichier des écritures d’une comptabilité que l’on pourrait rechercher par numéro de compte. On peut donc trouver sans recherche séquentielle la position du premier trou en consultant simplement la première fiche.soit de compacter périodiquement le fichier en ne recopiant que les fiches restant valides.. Sans compter l’obligation de recopier le nouveau fichier sur l’ancien. Cette table devra contenir pour chaque fiche la valeur de sa clé et le numéro de la fiche correspondante dans le fichier. Il n’est plus possible d’utiliser des algorithmes de recherche plus performants ( dichotomie. Une méthode fréquemment utilisée est d’inscrire dans la première fiche du fichier ( qui ne contient donc pas l’information normale ) le numéro de fiche du premier “ trou ” ou -1 s’il n’y en a aucun. Pour éviter toute réorganisation. etc. Il est donc capital que chaque fiche contienne une clé unique dans tout le fichier ( code produit. de détruire l’ancien fichier et de renommer le nouveau. Le premier trou contient le numéro du suivant et ainsi de suite jusqu’au dernier qui contient 1. La méthode proposée ici est de “ marquer ” la fiche comme supprimée en mettant une valeur particulière dans une de ses rubriques. Deux améliorations sont possibles : . Cette méthode aura l’avantage de la sûreté puisque l’on aura toujours sur le disque la copie de l’original.soit. il convient d’associer au fichier principal une table d'accès triée ( index ) que l’on sauvera dans un second fichier et qui devra être mis à jour lors de chaque modification du fichier principal ( technique du “ séquentiel indexé ” ). Elle est très efficace en temps ( 2 accès disque ). L’algorithme de recherche doit donc être de type séquentiel et ne permet donc de trouver que la première fiche ayant le critère recherché. FileSize ( F ) ) .. ou si le système le permet. Elle a néanmoins comme désavantage de laisser dans le fichier des “ trous ”.soit de modifier l’algorithme d’ajout pour qu’il recherche d’abord un “ trou ” avant de mettre la fiche en fin de fichier. comme nous l’avons fait avec les fichiers textes. En cas de récupération d’un trou. ). Le problème de la suppression est aussi délicat à gérer. Le même algorithme que la recherche pourrait être utilisé si la “ marque ” est une valeur particulière ( et impossible normalement ) d’une des rubriques de la fiche. ) et l’unicité de cette clé doit être maintenue lors des ajouts et des modifications. Ceci a l’avantage de permettre d’annuler une suppression tant que ce compactage n’a pas eu lieu. En espérant qu’il y aura sur le disque suffisamment de place pour deux copies du fichier. . Il n’est pas raisonnable de recopier le fichier dans un autre en “ oubliant ” la fiche à supprimer. on récupère le premier de la liste et on met à jour la première fiche pour qu’elle contienne le numéro du trou suivant ( ou -1 ) si ce trou était le dernier. Si on désire un ordre. Le fichier n’est pas ordonné mais l’index le sera. la création d’un second fichier sur lequel on écrira d’abord la nouvelle fiche puis ou l’on recopiera à la suite le contenu du fichier originel ( 10000 lectures et 10000 écritures de nouveau ). et donc d’encombrer inutilement le disque. Les fichiers - 32 . Le fichier ne peut donc pas être trié selon un critère de recherche. nom + prénom. c’est-à-dire par des opérations répétées d’insertion et de décalages des fiches pour les mettre à leur place dans l’ordre désiré. date ou journal d’imputation ). NouvelleFiche ) ) . Les recherches se feront alors exclusivement sur cette table qui délivrera en retour le numéro de la fiche cherchée. On constitue ainsi dans le fichier lui-même une liste chaînée des trous. Ces temps devront être multipliés par plusieurs dizaines si l’on effectue un tri de ce fichier. recherche avec sentinelle. DTA’ ) . Le programmeur doit s'assurer que la variable V a suffisamment d'espace pour le transfert tout entier. Reset ( F . Remarquez l'emploi du quatrième paramètre facultatif. La taille conseillée est de 1 octet . Var F : File . F est une variable de fichier sans type. { prêt pour un accès 1 octet à la fois} { prêt pour un accès 128 octets à la fois} { prêt pour un accès une fiche à la fois} Toutes les procédures et les fonctions de manipulation de fichiers. ou BlockRead ( Var F : File . Le paramètre facultatif NbLus ( ou NbEcrits ) retourne le nombre de fiches réellement transférées. NbALire : Integer . Read et Write sont remplacés par deux procédures BlockRead et BlockWrite qui attendent comme paramètre supplémentaire le nombre de fiches à lire ou à écrire. NbAEcrire : Integer ) . Assign ( F . FileSize et la procédure Seek qui utilisent la taille d’une fiche comme spécifiée par le programmeur dans Reset ou Rewrite ( ou 128 par défaut ). La syntaxe d'appel à ces procédures est : BlockRead ( Var F : File . Le programme suivant utilise des fichiers sans type pour dupliquer n’importe quel fichier. Sizeof ( tInfo ) ) . BlockWrite ( Var F : File . etc. les algorithmes de balayage séquentiel du fichier ( recherche. Var NbEcrits : Integer ) .Bien entendu. avec BlockRead. La fonction Eof fonctionne comme pour les fichiers typés. NbALire : Integer ) . Var V . Pour des raisons historiques. ainsi que les fonctions FilePos. les procédures Reset et Rewrite acceptent un paramètre supplémentaire optionnel permettant de spécifier la taille d’une fiche utilisée lors des transferts. ’PRODUIT.Var V . ou Reset ( F . Un appel à BlockRead ou BlockWrite avance le pointeur de fichier de NbLus ( ou NbEcrits ) enregistrements. ou Reset ( F ) . la taille par défaut est de 128 octets. Var V . Write sont autorisées sur les fichiers sans type. V est toute variable et NbALire ( ou NbAEcrire ) est une expression entière donnant le nombre de fiches ( dont la taille a été définie par le second paramètre de Reset ou Rewrite ) à transférer entre le fichier disque associé à F et la variable V. Var NbLus : Integer ) . NbAEcrire : Integer . ) doivent tester que la fiche courante n’est pas marquée comme supprimée. excepté Read. impression.1 ) . 12 Les fichiers non typés Dans le cas des fichiers non typés. BlockWrite ( Var F : File . recopie. Var V . Le transfert commence avec le premier octet occupé par la variable V. c'est en effet la seule valeur qui permette de manipuler correctement un fichier de n'importe quelle taille ( aucun enregistrement incomplet n'est à redouter lorsque la taille est de 1 ).33 . pour suivre le nombre d'enregistrements lus dans le fichier source et donc la fin de la copie : Les fichiers . . Sizeof ( C ) . Write. { les deux fichiers sans type} {les deux nomes externes} { le tampon d’échange} { contrôle du nombre octets lus} Begin Write ( 'nom du fichier source ') . Assign ( Dest . 1 ) . Read ( F . L’effort du concepteur a été pratiquement nul puisque les primitives de plus haut niveau ( Read. Tampon .doit exister } Write ( 'nom du fichier destination ' ) . ) appellent en fait celles de plus bas niveau avec les paramètres calculés automatiquement par le compilateur à partir du type des objets manipulés. 1 ) . { plus rien à lire dans la source} Close ( Source ) . Assign ( Source . { et recopier dans le fichier destination le nombre effectivement lus } If NbRecLus > 0 Then BlockWrite ( Dest . DestName : String . BlockWrite. SourceName ) . NbRecsLus : Integer . { 1 octet à la fois . Readln ( SourceName ) . ) est caractéristique de l’évolution du langage Pascal dans ses versions modernes. C ) . { 1 octet à la fois.Program CopieDeFichiers . En annulant ou en réduisant les contrôles de type normalement effectués par le compilateur. Tampon . If NbLus <> Sizeof ( C ) Then Ioresult := une valeur <> 0 Les fichiers - 34 . NbRecsLus ) .} Rewrite ( Dest .. NbRecsLus ) Until NbRecsLus = 0 . ) et de types génériques ( File. NbLus ) . C . Var Source .. { taille du tampon d’échange} Type tTampon = Array [ l. { prêt à la lecture du fichier source } Reset ( Source . on ajoute une plus grande souplesse d’utilisation au langage et on réduit de ce fait la différence avec les langages dit “ professionnels ” comme “ C ”. TailleTampon . doit être nouveau } Repeat { lire TailleTampon enregistrements dans le fichier source vers le tampon } { soit ici 10000 * 1 octets } BlockRead ( Source . Dest : File . La mise à la disposition des programmeurs de primitives de bas niveau ( BlockRead. { prêt à l’écriture du fichier destinat. Readln ( DestName ) . SourceName . Close ( Dest ) End . DestName ) . Const TailleTampon = 10000 ... est équivalent à BlockRead ( F .TailleTampon ] Of Byte .. Tampon : tTampon . exercice 12. les objets sont stockés dans le fichier sans aucun ordre et chacun est précédé d’un entier indiquant son type ( 0 = point. Y2 : Integer End .Write ( F . puisqu’elle sera en binaire. Y : Integer End . . Sizeof ( C ) . un rectangle tRect = Record X . 1 = Ligne. est équivalent à BlockWrite ( F. Cette méthode permet de créer des fichiers nommés des flots ( “ streams ” ) où des informations diverses sont écrites à la suite les unes des autres sans aucun contrôle de type par le langage.texte et en bénéficiant de la confidentialité de l’information puisqu’elle ne pourra être ni lue ni modifiée par un autre programme que le notre. ce qui n’est pas possible avec un fichier binaire typé. Les fichiers .DAT. chaque fiche devra être précédée d’un indicateur de son type ( et éventuellement du nombre de fois où elle est présente ) afin d’en permettre la relecture plus tard par un ordre BlockRead adapté. un cercle tCercle = Record X . H : Integer End . Y ... Y . NbEcrits ) . Y2 . un point tPoint= Record X . Ecrire un programme Pascal qui dessine la figure contenue dans le fichier DESSIN. 3 = cercle ).1(***) : un programme de dessin désire relire dans un unique fichier des objets graphiques de type différents comme: une ligne tLigne = Record X1 .. Y1 . 2 = rectangle. Bien entendu. C ) . On retrouve donc un des avantages des fichiers textes sans souffrir de la lenteur de la conversion binaire . If NbEcrits <> Sizeof ( C ) ) Then Ioresult := une valeur <> 0 Un autre intérêt des fichiers sans type est de pouvoir mettre dans un même fichier des informations de type différent. C .35 .. L . R : Integer End .
Copyright © 2024 DOKUMEN.SITE Inc.