FAQ PascalConsultez toutes les FAQ
Nombre d'auteurs : 10, nombre de questions : 402, dernière mise à jour : 7 janvier 2018 Ajouter une question
Bienvenue dans la F.A.Q. Pascal !
Celle-ci rassemble les réponses aux questions les plus fréquemment posées sur le langage Pascal et tous ses outils de programmation. Si elle n'a pas pour vocation de répondre à toutes les interrogations possibles, elle reste une bonne base de connaissances sur le Pascal, et ne demande qu'à être enrichie par vos expériences personnelles.
Nous vous invitons à proposer vos propres questions/réponses directement dans la FAQ ou, si vous souhaitez apporter une modification à une question/réponse existante, à la poster dans le fil de discussion renseigné ci-dessous.
Nous vous souhaitons une bonne lecture !
L'équipe Pascal.
- Comment copier un fichier ?
- Comment déplacer un fichier ?
- Comment supprimer un fichier ?
- Comment renommer un fichier ?
- Comment tester l'existence d'un fichier ?
- Comment rechercher un ou plusieurs fichiers sur disque ?
- Pourquoi ne peut-on ouvrir un fichier alors qu'il existe ?
- Comment créer un dossier (répertoire) ?
- Comment supprimer un dossier (répertoire) ?
- Comment déterminer le nom de volume d'un disque ?
Pour copier un fichier, il faut se servir des procédures BlockRead et BlockWrite en utilisant tous les paramètres disponibles. La copie s'effectue en plusieurs étapes :
- créer le fichier de destination (Rewrite) ;
- ouvrir le fichier source (Reset) ;
- lire le contenu du fichier source (BlockRead) et écrire dans le fichier destination (BlockWrite) ;
- fermer les fichiers (Close).
- créer le fichier de destination (Rewrite) ;
- ouvrir le fichier source (Reset) ;
- lire le contenu du fichier source (BlockRead) et écrire dans le fichier destination (BlockWrite) ;
- fermer les fichiers (Close).
Prenons un exemple. Le fichier source est Source, et le fichier destination Dest. Le tampon de copie est Buffer, d'une taille de 1 Ko et Count est le nombre d'octets copiés à chaque passe.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | Function CopyFile (const SourceFile, DestFile : String) : Boolean; Var Source, Dest : File; Buffer : Array [0..1023] of Byte; Count : Word; OldFileMode : Word; Begin CopyFile := True; { Désactivation des erreurs E/S } {$I-} { Assignation des fichiers } Assign(Source,SourceFile); Assign(Dest,DestFile); { Ouverture en lecture seule de Source et création de Dest } OldFileMode := FileMode; FileMode := 0; Reset(Source,1); if IOResult = 0 then begin Rewrite(Dest,1); if IOResult = 0 then begin { Boucle principale de copie, s'arrête quand la fin du fichier est atteinte } repeat { Remplissage du buffer : 1 Ko prévus, Count octets réels } BlockRead(Source,Buffer,SizeOf(Buffer),Count); { Ecriture du contenu du buffer } BlockWrite(Dest,Buffer,Count); until (Count = 0) or (Count <> SizeOf(Buffer)); { Fermeture du fichier } Close(Dest); if IOResult <> 0 then { Erreur de fermeture du nouveau fichier } CopyFile := False; end else { Erreur de création du nouveau fichier } CopyFile := False; { Fermeture du fichier } Close(Source); end else { Erreur d'ouverture du fichier original } CopyFile := False; { Réactivation des erreurs d'E/S et rétablissement du mode de lecture } FileMode := OldFileMode; {$I+} End; |
Le Pascal standard ne permet pas de déplacer directement un fichier. Il faut procéder en deux étapes successives :
- copier le fichier source vers la destination ;
- supprimer le fichier original.
Pour le source de la fonction CopyFile, reportez-vous à la question concernant la copie de fichier.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | Uses Dos; Function CopyFile (const SourceFile, DestFile : String) : Boolean; ... Function MoveFile (const FileName, Path : String) : Boolean; Var S, Dir, FName, Ext : String; f : File; begin S := Path; if S[Length(S)] <> '\' then S := S + '\'; FSplit(FileName,Dir,FName,Ext); S := S + FName + Ext; if CopyFile(FileName, S) then begin Assign(f, FileName); {$I-} Erase(f); {$I+} MoveFile := (IOResult = 0); end else MoveFile := False; end; |
Pour supprimer un fichier, il faut recourir à la procédure Erase (var f) sur un fichier assigné - :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | Var f : File; Begin ... Assign(f,'TEST.TXT'); Erase(f); ... End. |
Pour renommer un fichier, servez-vous de la procédure Rename (var f; Name : String) sur un fichier assigné :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | Var f : File; Begin ... Assign(f,'OLD.TXT'); Rename(f,'NEW.TXT'); ... End. |
Exemple
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | Var f : File; Begin ... Assign(f,'C:\TEST\OLD.TXT'); Rename(f,'C:\TEST\NEW.TXT'); { On précise aussi le répertoire } ... End. |
Deux manières sont envisageables : soit tenter d'ouvrir le fichier et vérifier si une erreur s'est produite; soit faire une recherche.
- 1re méthode : tenter d'ouvrir le fichier
Cette première méthode demande une précision préalable. En effet, s'il s'avère que le fichier que l'on recherche est en lecture seule, il faudra prendre garde à ne tenter une ouverture qu'en lecture seule. Or, par défaut, l'ouverture d'un fichier s'effectue en lecture-écriture. On changera donc les options d'ouverture des fichiers avant la vérification, pour ensuite les rétablir.
Autre détail : le périphérique NULL, ayant pour nom 'NULL', peut toujours être ouvert. Or, ce n'est pas un vrai fichier. On l'éliminera donc dans notre code.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Function FileExists (const FileName : String) : Boolean; Var f : File; OldFileMode : Word; Result : Boolean ; Begin Result := (FileName <> 'NULL'); { Result = false si FileName = 'NULL' } if Result then { on ne fait d'autres contrôles que si Result = True } begin OldFileMode := FileMode; { On modifie la méthode d'ouverture : lecture seule } FileMode := 0; {$I-} Assign(f, FileName); Reset(f,1); { Tentative d'ouverture } Result := (IOResult = 0); Close(f); {$I+} FileMode := OldFileMode; { On restaure le mode d'ouverture } end; FileExists := Result ; End; |
- 2e méthode : la recherche de fichier
Cette méthode recourt à FindFirst et donc à l'unité Dos. On prendra garde d'éliminer tout répertoire ou nom de volume de notre recherche.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | Uses Dos; Function FileExists (const FileName : String); Var S : SearchRec; Begin FindFirst(FileName,AnyFile,S); FileExists := (DosError = 0) and (S.Attr and (VolumeID or Directory) = 0); { Si vous n'utilisez pas Turbo Pascal, ajoutez la ligne : } { FindClose(S); } End; |
Afin de rechercher un fichier sur le disque dur, disquette ou bien CD-ROM, il faut recourir aux fonctions FindFirst, FindNext et FindClose de l'unité Dos.
Une recherche de fichiers s'effectue toujours en plusieurs étapes :
- l'initialisation de la recherche ;
- la recherche itérative des fichiers correspondant à certains critères ;
- la clôture de la recherche.
Il est à noter que la dernière étape peut être facultative sur certains compilateurs et/ou systèmes d'exploitation. C'est notamment le cas de Turbo Pascal, qui ne fait pas usage de FindClose (cette procédure n'est alors pas déclarée).
L'initialisation d'une recherche s'effectue avec FindFirst (Path : String; Attr : Word; var S : SearchRec); où :
- Path correspond au nom de fichier recherché. Les caractères génériques (jokers) sont autorisés ('*.TXT' par exemple') ;
- Attr désigne les attributs de fichier réclamés pour la recherche (voir le tableau ci-dessous) ;
- S est la structure recevant le résultat de la recherche.
Le paramètre Attr peut prendre les valeurs suivantes :
Constante | Valeur | Attribut |
ReadOnly (ou faReadOnly) | $01 | Fichier en lecture seule |
Hidden (ou faHidden) | $02 | Fichier caché |
SysFile (ou faSysFile) | $04 | Fichier système |
VolumeID (ou faVolumeID) | $08 | Nom de volume d'un disque |
Directory (ou faDirectory) | $10 | Répertoire |
Archive (ou faArchive) | $20 | Fichier archive (attribut par défaut) |
AnyFile (ou faAnyFile) | $3F | Tous les attributs ensemble |
La variable S : SearchRec contient le résultat d'une recherche, fichier par fichier. En effet, une recherche de fichiers s'effectue de manière itérative, et on ne peut obtenir qu'un seul fichier à la fois. C'est pourquoi il faut faire appel à FindNext (var S : SearchRec), qui se charge de rechercher le fichier suivant correspondant aux critères de départ.
Lorsque tous les fichiers ont été trouvés, on fait appel à FindClose (var S : SearchRec) pour clôturer la recherche.
Il se peut qu'aucun fichier ne soit trouvé. Ainsi, il convient d'utiliser une boucle de type while (et non repeat) lors d'une recherche.
Bien entendu, il faut savoir lorsque la recherche est terminée, autrement dit lorsque tous les fichiers correspondant à nos critères ont été trouvés. Pour cela, deux méthodes différentes existent en fonction du compilateur utilisé :
- tester la variable DosError : elle vaut 0 tant que la recherche ne pose pas de problèmes ;
- tester la valeur de retour de FindFirst et FindNext : une valeur nulle indique que la recherche se poursuit.
Prenons des exemples concrets à présent :
- Recherche de fichiers
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Program ChercheText; Uses Dos; Var S : SearchRec; Begin { Recherche des fichiers texte du disque C, ayant l'attribut archive } FindFirst('C:\*.TXT',Archive,S); while DosError = 0 do { Tant qu'il n'y a pas d'erreurs... } begin WriteLn(S.Name); { Affichage du nom du fichier } FindNext(S); { Recherche de la prochaine occurrence } end; FindClose(S); { Clôture la recherche (ligne à supprimer avec Turbo Pascal) } End. |
- Recherche de dossiers (répertoires)
Parfois, les dossiers sont mal rapportés. On préfèrera donc le plus souvent faire une recherche générale (*.*) et tester l'attribut S.Attr directement. De plus, il faut savoir que chaque dossier contient deux sous-dossiers « fictifs », nommés "." et "..". Le premier représente le dossier en lui-même et le deuxième le dossier parent. Soyez donc prudent afin de ne pas créer une boucle infinie en examinant sans cesse le répertoire ".".
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Program ListeDir; Uses Dos; Var S : SearchRec; Begin FindFirst('C:\*.*',Directory,S); while DosError = 0 do begin WriteLn(S.Name); FindNext(S); end; FindClose(S); End. |
- 2e méthode : si votre compilateur déclare FindFirst et FindNext comme fonctions, il ne faut pas utiliser DosError :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | Begin ... if FindFirst('*.TXT',faArchive,S) = 0 then begin repeat ... until FindNext(S) <> 0; FindClose(S); end; ... End; |
Parfois, lorsque l'on tente d'ouvrir un fichier, il se produit une erreur d'accès disque. Cela peut provenir du fait que le fichier est en lecture seule. En effet, par défaut, les fichiers sont ouverts en lecture et écriture. Or, un fichier en lecture seule, par définition, ne peut être ouvert qu'en lecture.
Heureusement, il est possible de choisir le mode d'ouverture des fichiers. Pour cela, il faut se servir de la variable FileMode. Les valeurs possibles les plus courantes affectant Reset sont :
Valeur | Signification |
0 | Lecture seule |
1 | Écriture seule |
2 | Lecture et écriture |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Var f : file; OldFMode : Word; Begin OldFMode := FileMode; {$I-} FileMode := 0; { Passage en lecture seule } Assign(f, 'FICHIER.EXT'); Reset(f,1); ... Close(f); {$I+} FileMode := OldFMode; End; |
Pour créer un dossier, il faut se servir de la procédure MkDir (Path : string) de l'unité Dos :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | Uses Dos; Begin ... MkDir('C:\TEST'); ... End. |
Pour supprimer un dossier, il faut se servir de la procédure RmDir (Path : string) de l'unité Dos :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | Uses Dos; Begin ... RmDir('C:\TEST'); ... End. |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | Uses Dos; Procedure Deltree (Path : string); Var S : SearchRec; f : File; L : Byte; Begin { On fait en sorte que le chemin ne se termine pas par '\' } L := Length(Path); if Path[L] = '\' then Delete(Path,L,1); { On recherche tous les fichiers possibles } FindFirst(Path + '\*.*', ReadOnly or SysFile or Archive or Directory, S); while DosError = 0 do begin { Si c'est un répertoire (sauf . et ..), on le supprime } if S.Attr and Directory <> 0 then begin if (S.Name <> '.') and (S.Name <> '..') then Deltree(Path + '\' + S.Name); end else begin { Sinon, il s'agit d'un fichier, que l'on va supprimer } Assign(f,Path + '\' + S.Name); { On le passe en Archive, sinon, on ne peut pas le supprimer } SetFAttr(f,Archive); { On le supprime } Erase(f); end; { On passe au fichier suivant } FindNext(S); end; { Si vous n'utilisez pas Turbo Pascal, ajoutez la ligne : } { FindClose(S); } { On supprime le répertoire vide } RmDir(Path); End; Begin Deltree('C:\TEST'); End. |
Pour obtenir le nom de volume d'un disque, on peut se servir de la fonction de recherche de fichiers FindFirst :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Program VolumeDisque; Uses Dos; Var S : SearchRec; Begin FindFirst('C:\',VolumeID,S); if DosError = 0 then begin WriteLn('C: [', S.Name, ']'); FindClose(S); { Supprimez cette ligne si vous compilez en Turbo Pascal } end; End. |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.