Outils pour utilisateurs

Outils du site


perl:utilisation_des_fichiers

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
perl:utilisation_des_fichiers [2009/03/15 00:49] – créée rootperl:utilisation_des_fichiers [2013/03/12 23:36] (Version actuelle) root
Ligne 1: Ligne 1:
-== 1. Descripteurs ==+====== Les fichiers ======
  
-Pour manipuler un fichier, il faut d'abord obtenir une "poignée" ou "descripteur" (''handle'') permettant de le saisir.+====== 1Descripteurs ======
  
-=== Syntaxes ===+Pour manipuler un fichier, il faut d'abord obtenir une "poignée" ou "descripteur" (//handle//) permettant de le saisir. 
 + 
 +===== Syntaxes =====
  
 Perl peut également manipuler ces descripteurs avec deux types de syntaxe. La syntaxe "ancienne" ou traditionnelle utilise des noms en majuscules avec uniquement des lettres, et ne sont jamais déclarés et assignés. La portée de ces descripteurs est globale : Perl peut également manipuler ces descripteurs avec deux types de syntaxe. La syntaxe "ancienne" ou traditionnelle utilise des noms en majuscules avec uniquement des lettres, et ne sont jamais déclarés et assignés. La portée de ces descripteurs est globale :
- open(TEXT, ">text"); +<code perl> 
- print TEXT "Bonjour le monde.\n"; +  open(TEXT, ">text"); 
- close(TEXT);+  print TEXT "Bonjour le monde.\n"; 
 +  close(TEXT); 
 +</code>
  
 La deuxième syntaxe, plus "attendue" permet d'utiliser une variable standard et donc locale (il s'agit en fait d'une référence vers un descripteur) : La deuxième syntaxe, plus "attendue" permet d'utiliser une variable standard et donc locale (il s'agit en fait d'une référence vers un descripteur) :
- open(my $text, ">text"); +<code perl> 
- print $text "Bonjour le monde.\n"; +  open(my $text, ">text"); 
- close($text);+  print $text "Bonjour le monde.\n"; 
 +  close($text); 
 +</code>
  
-Notons qu'il existe une version moderne (orienté objet) qui requiert l'utilisation d'un module spécifique (cf ''man filehandle'') : +Notons qu'il existe une version moderne (orienté objet) qui requiert l'utilisation d'un module spécifique (cf //man filehandle//) : 
- use FileHandle; +<code perl> 
-  +  use FileHandle; 
- $text = new FileHandle(">text"); +   
- print $text "Bonjour le monde.\n"; +  $text = new FileHandle(">text"); 
- $text->close();+  print $text "Bonjour le monde.\n"; 
 +  $text->close(); 
 +</code>
  
-=== Descripteurs implicites ===+===== Descripteurs implicites =====
  
 Perl utilise plusieurs descripteurs implicites par défaut, qui peuvent être nommés: Perl utilise plusieurs descripteurs implicites par défaut, qui peuvent être nommés:
-'''STDOUT''': l'entrée standard, qui est naturellement utilisée par ''print'' et consorts +  * **STDOUT**: l'entrée standard, qui est naturellement utilisée par //print// et consorts 
-'''STDERR''': la sortie d'erreur, utilisée notamment par ''die'' +  * **STDERR**: la sortie d'erreur, utilisée notamment par //die// 
-'''STDIN''': l'entrée standard, utilisée par défaut par l'opérateur de lecture ''<>''+  * **STDIN**: l'entrée standard, utilisée par défaut par l'opérateur de lecture //<>//
  
-== 2. Ouverture ==+====== 2. Ouverture ======
  
-=== Via le shell ===+===== Via le shell =====
  
 La façon la plus économique d'ouvrir un fichier et de ne pas le faire, ou plus simplement de déléguer cette tâche au shell. Ainsi il suffit d'appeler l'interpréteur Perl en redirigeant les fichiers ou programmes de son choix sur l'entrée ou la sortie standard : La façon la plus économique d'ouvrir un fichier et de ne pas le faire, ou plus simplement de déléguer cette tâche au shell. Ainsi il suffit d'appeler l'interpréteur Perl en redirigeant les fichiers ou programmes de son choix sur l'entrée ou la sortie standard :
- $ ./test.pl <input 2>error.log |grep qqchose+  $ ./test.pl <input 2>error.log |grep qqchose
  
-=== Mode simple ===+===== Mode simple =====
  
-On utilise la fonction ''open'', qui accepte comme nom de fichier une syntaxe ressemblant au shell et permettant de désigner les différents scenarios d'ouverture :+On utilise la fonction //open//, qui accepte comme nom de fichier une syntaxe ressemblant au shell et permettant de désigner les différents scenarios d'ouverture :
  
-{| bgcolor="#f7f8ff" cellpadding="3" cellspacing="0" border="1" style="font-size: 95%; border: gray solid 1px; border-collapse: collapse;" +^ **open(FILE, "test")** ^ Lecture seule^ 
-|-  +**open(FILE, "<test")** | Lecture seule| 
-| '''open(FILE, "test")''' || Lecture seule +**open(FILE, ">test")** | Ecriture avec troncature| 
-|+**open(FILE, ">>test")** | Ecriture en fin de fichier| 
-| '''open(FILE, "<test")''' || Lecture seule +**open(FILE, "+<test")** | Lecture/écriture (fichier existant, sans troncature)| 
-|- +**open(FILE, "+>test")** | Lecture/écriture (troncature, création de fichier si nécessaire)| 
-'''open(FILE, ">test")''' || Ecriture avec troncature +**open(FILE, "+>>test")** | Lecture/écriture (sans troncature, écriture depuis la fin, création de fichier si nécessaire)|
-|- +
-'''open(FILE, ">>test")''' || Ecriture en fin de fichier +
-|- +
-'''open(FILE, "+<test")''' || Lecture/écriture (fichier existant, sans troncature) +
-|- +
-'''open(FILE, "+>test")''' || Lecture/écriture (troncature, création de fichier si nécessaire) +
-|- +
-'''open(FILE, "+>>test")''' || Lecture/écriture (sans troncature, écriture depuis la fin, création de fichier si nécessaire) +
-|}+
  
-=== Avec une variable ===+===== Avec une variable =====
  
 Il est important de noter qu'avec l'utilisation de variables classiques Perl, un fichier est automatiquement fermé dès que l'on quitte la portée de la variable : Il est important de noter qu'avec l'utilisation de variables classiques Perl, un fichier est automatiquement fermé dès que l'on quitte la portée de la variable :
- sub log_error {+<code perl> 
 +  sub log_error {
   open(my $log, ">>error.log") or die;   open(my $log, ">>error.log") or die;
   print $log @_;   print $log @_;
- }+  } 
 +</code>
  
-=== Avec des programmes ===+===== Avec des programmes =====
  
 On peut facilement reproduire le mécanisme du "pipe" utilisé dans le shell, c'est-à-dire relier sur l'entrée ou la sortie standard un autre programme : On peut facilement reproduire le mécanisme du "pipe" utilisé dans le shell, c'est-à-dire relier sur l'entrée ou la sortie standard un autre programme :
- open(MAIL, "|sendmail -bi") or die; +<code perl> 
- print MAIL "From: eleve@insia.org\r\nSubject: test\r\n"; +  open(MAIL, "|sendmail -bi") or die; 
- close MAIL; +  print MAIL "From: eleve@insia.org\r\nSubject: test\r\n"; 
-  +  close MAIL; 
- open(LOG, "gzip mail.1.gz|") or die; +   
- while(<LOG>) { +  open(LOG, "gzip mail.1.gz|") or die; 
-   print $_ if /error/; +  while(<LOG>) { 
- } +  print $_ if /error/; 
- close FILES;+  
 +  close FILES; 
 +</code>
  
-Ceci implique bien entendu que Perl se charge d'exécuter ces programmes à votre demande, c'est une forme altrenative d'invocation de commande (cf. ''system'' et l'opérateur ''backtick'').+Ceci implique bien entendu que Perl se charge d'exécuter ces programmes à votre demande, c'est une forme altrenative d'invocation de commande (cf. //system// et l'opérateur //backtick//).
  
-'''Note''': pour la communication bi-directionnelle avec un programme, voir le module ''IPC::Open2''.+**Note**: pour la communication bi-directionnelle avec un programme, voir le module //IPC::Open2//.
  
  
-=== Le fichier '-' ===+===== Le fichier '-' =====
  
-Il existe un fichier spécial nommé '''-''' (moins, ''minus'') qui permet de désigner l'entrée standard ou la sortie standard du script, selon la direction utilisée. Il est notable que si on utilise le préfixe ''pipe'', le programme exécuté est une autre instance du script (en d'autre termes, il s'agit d'un ''fork'' déguisé).+Il existe un fichier spécial nommé **-** (moins, //minus//) qui permet de désigner l'entrée standard ou la sortie standard du script, selon la direction utilisée. Il est notable que si on utilise le préfixe //pipe//, le programme exécuté est une autre instance du script (en d'autre termes, il s'agit d'un //fork// déguisé).
  
-=== Appels systèmes directs ===+===== Appels systèmes directs =====
  
-Les fonctions d'ouvertures (puis de lecture/écriture) de Perl reposent sur leur équivalent libc ''fopen, fread, ...''. On profite ainsi de mécanismes haut niveau: pas de gestion de buffers, d'écritures partielles, etc. Parfois cela peut être un obstacle, surtout si l'on cherche à communiquer avec des fichiers spéciaux (périphériques) ou en utilisant des protocoles binaires.+Les fonctions d'ouvertures (puis de lecture/écriture) de Perl reposent sur leur équivalent libc //fopen, fread, ...//. On profite ainsi de mécanismes haut niveau: pas de gestion de buffers, d'écritures partielles, etc. Parfois cela peut être un obstacle, surtout si l'on cherche à communiquer avec des fichiers spéciaux (périphériques) ou en utilisant des protocoles binaires.
  
 Dans ce cas on peut utiliser les appels systèmes POSIX standard : Dans ce cas on peut utiliser les appels systèmes POSIX standard :
- use Fcntl; # Imports O_xxx constants +<code perl> 
-  +  use Fcntl; # Imports O_xxx constants 
- sysopen(FILE, "/dev/ttyS0", O_RDWR) or die; +   
- while(sysread(FILE, $buf, 32))  +  sysopen(FILE, "/dev/ttyS0", O_RDWR) or die; 
-  my $to_say  = "You said: $buf\n";+  while(sysread(FILE, $buf, 32)) { 
 +  my $to_say = "You said: $buf\n";
   my $to_send = length($to_say);   my $to_send = length($to_say);
-  my $sent    = syswrite(FILE, $to_say, $to_send);+  my $sent = syswrite(FILE, $to_say, $to_send);
   print "transmit: $sent/$to_send\n";   print "transmit: $sent/$to_send\n";
- }  +  
- close FILE;+  close FILE; 
 +</code>
  
-=== Mode binaire ===+===== Mode binaire =====
  
 Sur certains systèmes aux concepts curieux, le mode par défaut d'accès à un fichier n'est pas transparent (un octet pour un octet), mais interprété. Typiquement, un "\n" sera réellement écrit "\r\n" sous MS Windows. On doit alors utiliser explicitement un mode "binaire" pour ces systèmes (la fonction sera sans effet sur les systèmes conventionnels) : Sur certains systèmes aux concepts curieux, le mode par défaut d'accès à un fichier n'est pas transparent (un octet pour un octet), mais interprété. Typiquement, un "\n" sera réellement écrit "\r\n" sous MS Windows. On doit alors utiliser explicitement un mode "binaire" pour ces systèmes (la fonction sera sans effet sur les systèmes conventionnels) :
- binmode(FILE);+  binmode(FILE);
  
  
-== 3. Lecture ==+====== 3. Lecture ======
  
-=== Par blocs ===+===== Par blocs =====
  
-On peut lire une quantité de donnée quelconque depuis un fichier simplement à l'aide de ''read'' +On peut lire une quantité de donnée quelconque depuis un fichier simplement à l'aide de //read// 
- read(FILE, $buffer, 1500); +<code perl> 
- read(FILE, $buffer, 1500, 2000); # Lit à partir du 2000ème octet +  read(FILE, $buffer, 1500); 
- seek(FILE, 5000); # Positionne le curseur de lecture au 5000ème octet+  read(FILE, $buffer, 1500, 2000); # Lit à partir du 2000ème octet 
 +  seek(FILE, 5000); # Positionne le curseur de lecture au 5000ème octet 
 +</code>
  
-=== Par enregistrement ===+===== Par enregistrement =====
  
-Il s'agit de l'utilisation de loin la courante en Perl, elle est même intégrée en tant qu'opérateur : ''<>''. Le séparateur d'enregistrement peut être modifiée à tout moment à l'aide de la variable spéciale ''$/'' (qui désigne le retour chariot par défaut) : +Il s'agit de l'utilisation de loin la courante en Perl, elle est même intégrée en tant qu'opérateur : //<>//. Le séparateur d'enregistrement peut être modifiée à tout moment à l'aide de la variable spéciale //$/// (qui désigne le retour chariot par défaut) : 
- <nowiki+<code perl
- $/ = "\n\n"; # Découpe en "paragraphes" +  $/ = "\n\n"; # Découpe en "paragraphes" 
- while (<FILE>) {+  while (<FILE>) {
   print "<p> $_ </p>\n";   print "<p> $_ </p>\n";
- +  
- </nowiki>+</code>
  
-L'opérateur renvoie le dernier enregistrement lu, ou ''undef'' si la fin du fichier est rencontré. Il est ainsi traditionnellement appelé dans le test d'une boucle ''while'', l'enregistrement courant étant alors implicitement dans la variable ''$_''+L'opérateur renvoie le dernier enregistrement lu, ou //undef// si la fin du fichier est rencontré. Il est ainsi traditionnellement appelé dans le test d'une boucle //while//, l'enregistrement courant étant alors implicitement dans la variable //$_//.
  
 Il est possible de lire un fichier entier en un seul appel en utilisant la chaîne vide comme séparateur : Il est possible de lire un fichier entier en un seul appel en utilisant la chaîne vide comme séparateur :
- $/ = ""; +<code perl> 
- my $whole = <FILE>; # Lit tout le fichier dans $whole +  $/ = ""; 
-  +  my $whole = <FILE>; # Lit tout le fichier dans $whole 
-'''Note''': une technique alternative, empruntée au shell serait ''my $whole = `cat $filename`;''.+</code>
  
-== 4Ecriture ==+**Note**: une technique alternative, empruntée au shell serait //my $whole `cat $filename`;//.
  
-=== Formatée ===+====== 4. Ecriture ======
  
-Il existe de nombreuses fonctions de formattage, dont les fameux ''print'', ''printf'', ''write'' et ''format''+===== Formatée =====
- print FILE "Une information...\n";+
  
-'''Note''': ''write' n'est '''pas''' le pendant de ''read'' ! (Il n'est pas nécessaire, il suffit de manipuler les chaînes et uiliser ''seek'').+Il existe de nombreuses fonctions de formattage, dont les fameux //print//, //printf//, //write// et //format// : 
 +<code perl> 
 +  print FILE "Une information...\n"; 
 +</code>
  
-=== Sortie par défaut ===+**Note**: //write// n'est **pas** le pendant de //read// ! (Il n'est pas nécessaire, il suffit de manipuler les chaînes et uiliser //seek//). 
 + 
 +===== Sortie par défaut =====
  
 Il est possible de changer momentanément le fichier de sortie par défaut, ce qui permet de rediriger facilement la sortie d'un sous-programme sans avoir à le modifier : Il est possible de changer momentanément le fichier de sortie par défaut, ce qui permet de rediriger facilement la sortie d'un sous-programme sans avoir à le modifier :
- make_report(); # Sortie sur STDOUT +<code perl> 
- my $previous = select(LOG); +  make_report(); # Sortie sur STDOUT 
- make_report(); # Sortie dans LOG +  my $previous = select(LOG); 
- select($previous);+  make_report(); # Sortie dans LOG 
 +  select($previous); 
 +</code>
  
 +===== Bufferisation =====
  
-=== Bufferisation ===+Par défaut, les appels haut niveau (par opposition à //sysread//) sont bufferisés par la bibliothèque C standard, pour économiser les appels systèmes. Ce n'est parfois pas désirable, par exemple lorsque l'on veut fournir une sortie caractère par caractère animée (barre de progression, etc).
  
-Par défaut, les appels haut niveau (par opposition à ''sysread'') sont bufferisés par la bibliothèque C standard, pour économiser les appels systèmes. Ce n'est parfois pas désirable, par exemple lorsque l'on veut fournir une sortie caractère par caractère animée (barre de progression, etc). +On peut facilement outrepasser ce cache, par exemple pour la sortie courante (STDOUT par défaut, mais cf. //select//) : 
- +<code perl> 
-On peut facilement outrepasser ce cache, par exemple pour la sortie courante (STDOUT par défaut, mais cf. ''select'') : +  $| = 1; # Autoflush = 1 
- $| = 1; # Autoflush = 1+</code>
  
 Et il existe une syntaxe plus générique fonctionnant sur tous les descripteurs de fichiers, mais elle nécessite le module orienté objet : Et il existe une syntaxe plus générique fonctionnant sur tous les descripteurs de fichiers, mais elle nécessite le module orienté objet :
- use FileHandle; +<code perl> 
-  +  use FileHandle; 
- open(my $tty, ">/dev/tty"); +   
- $tty->autoflush(1); +  open(my $tty, ">/dev/tty"); 
 +  $tty->autoflush(1); 
 +</code>
perl/utilisation_des_fichiers.1237078195.txt.gz · Dernière modification : 2009/03/15 00:49 de root