FAQ PascalConsultez toutes les FAQ

Nombre d'auteurs : 10, nombre de questions : 400, dernière mise à jour : 12 septembre 2016  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.

Commentez


SommaireLe langage PascalLes fichiers (10)
précédent sommaire suivant
 

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).
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).

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;
Dans cet exemple, on n'a pas vérifié si le fichier de destination existe déjà ou non. Si tel est le cas, alors celui-ci sera écrasé sans sommation.

Mis à jour le 18 avril 2004 droggo Eric Sigoillot

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;

Mis à jour le 18 avril 2004 Eric Sigoillot

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.
Il ne faut jamais utiliser Erase sur un fichier ouvert !

Mis à jour le 3 avril 2004 Eric Sigoillot

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.
Si vous renommez un fichier dans un autre répertoire que le répertoire en cours, vous devez en plus du nouveau nom indiquer aussi totalement le chemin d'accès au fichier, sans quoi une erreur se produirait.

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.

Mis à jour le 3 avril 2004 Eric Sigoillot

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;

Mis à jour le 7 mars 2004 droggo Eric Sigoillot

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
Tous ces attributs peuvent bien sûr être combinés (or) afin, par exemple, de rechercher des fichiers système en lecture seule, etc.

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;

Mis à jour le 3 avril 2004 Eric Sigoillot Giovanny Temgoua

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
Par conséquent, avant d'essayer d'ouvrir un fichier en lecture seule, on modifiera la valeur de FileMode. Voici un exemple :

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;

Mis à jour le 16 mai 2004 Eric Sigoillot

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.

Mis à jour le 3 avril 2004 Eric Sigoillot

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.
La procédure RmDir ne peut supprimer qu'un dossier vide, sinon elle déclenche une erreur. L'exemple suivant implémente une procédure récursive Deltree qui se charge de supprimer tout le contenu du dossier avant de supprimer le dossier en lui-même :

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.

Mis à jour le 3 avril 2004 Eric Sigoillot

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.

Mis à jour le 3 avril 2004 Eric Sigoillot Giovanny Temgoua

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2017 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.

 
Responsables bénévoles de la rubrique Pascal : Gilles Vasseur - Alcatîz -