FAQ PerlConsultez toutes les FAQ

Nombre d'auteurs : 18, nombre de questions : 250, dernière mise à jour : 29 octobre 2015  Ajouter une question

 

Bienvenue sur la FAQ Perl. Cette FAQ a pour vocation de vous enseigner ou de vous faire revoir les notions élémentaires de ce fantastique langage. Perl est très utilisé dans différents domaines depuis la gestion système, le réseaux, l'administration de bases de données, le web (CGI), la bureautique, la conception d'interfaces graphiques ou des contextes scientifiques telle la bioinformatique. Nous espérons que cette FAQ vous sera d'une grande utilité.

Vous souhaitez participer à l'amélioration de cette FAQ, n'hésitez pas !! Commentez

Bonne lecture !


SommairePerl avancéLes fichiers (11)
précédent sommaire suivant
 

Dans les précédentes parties, vous avez conçu vos programmes Perl pour que ceux-ci puissent converser via les entrées/sorties (E/S) standard à savoir : STDIN (le clavier), STDOUT (la console) et STDERR (sortie standard en cas d'erreur).
Dans ce chapitre, nous allons maintenant apprendre à lire à partir des fichiers stockés sur un média (disque dur, CDROM, disquette...). Le langage Perl nécessite pour la lecture/écriture de fichiers des handles.
Un handle n'est qu'une connexion entre votre programme Perl et le fichier à lire ou à écrire. Il existe déjà six handles de fichiers réservés : STDIN (soit le flux d'entrée standard), STDOUT (flux de sortie standard), STDERR (direction des erreurs), DATA, ARGV et ARGVOUT.

Vous lirez dans certaines documentations le mot "file handle". Il correspond tout simplement à un identifiant du fichier après ouverture, une sorte de descripteur du fichier.

Mis à jour le 8 mai 2005 djibril GLDavid

Rien ne vous empêche dans Perl de créer et nommer vos propres descripteur de fichier (filehandle)s. De même, les connaisseurs d'Unix seront sans doute ravis de savoir que les redirections d'entrées/sorties standards sont primordiales pour indiquer au descripteur de fichier (filehandle) la direction du flux. Voici d'ailleurs un exemple pour illustrer l'ouverture d'un fichier en Perl. Nous supposerons qu'il existe dans le même répertoire que notre script un fichier "toto.txt" :

Code perl : Sélectionner tout
open my $fh, '<', "toto.txt";
Dans cet exemple, le chevron "<" indique que nous sommes en lecture. Bien naturellement, il est envisageable de mettre dans une variable scalaire le chemin de votre fichier :

Code perl : Sélectionner tout
1
2
$chemin = "/home/gldavid/toto.txt"; 
open my $fh, '<', $chemin;
L'écriture reprend la même syntaxe, sauf que vous aurez deux méthodes :

Code perl : Sélectionner tout
1
2
open my $fh, '>', "toto.txt"; 
open my $fh, '>>', "tata.txt";
Quelle est la différence entre ces deux instructions ? Les amateurs d'Unix vous diront que dans le premier cas, nous écrivons sur toto.txt. Si celui-ci n'existe pas, Perl le crée avant d'écrire dans ce fichier. Dans le cas où celui-ci existe déjà, le contenu sera écrasé par le traitement effectué.
Dans le deuxième cas, si le fichier tata.txt n'existe pas, Perl le crée puis procède à l'écriture. Dans le cas où le fichier existe au préalable, Perl écrit à la suite du contenu.

Enfin, il s'agit de procéder proprement.
Comme dans tous les langages, dès que vous ouvrez un flux, pensez à le fermer !

Code perl : Sélectionner tout
1
2
3
open my $fh, '>>', "toto.txt"; 
#Je lis le fichier toto.txt et j'exécute mon traitement 
close($fh);
L'instruction close sur un descripteur de fichier (filehandle) permet de fermer tout lien entre votre processus Perl et le fichier visé.

Veuillez lire les sections suivantes pour en savoir plus.

Mis à jour le 8 mai 2005 djibril GLDavid

Naturellement, il se peut que vous vous trompiez dans le chemin de votre fichier. Pour le cas où vous souhaitez gérer de telles exceptions, Perl vous offre le choix de tuer votre application et de pouvoir disposer d'un message d'erreur. La close die produit un tel message :

Code perl : Sélectionner tout
1
2
3
4
open FILE, "< toto.txt" or die "toto.txt n'existe pas !\n"; 
while ($ligne = <FILE>) { 
print "$ligne\n"; 
}
Lorsque votre script Perl arrive à cette instruction et si celui-ci ne trouve pas le fichier toto.txt, la close die entre en jeu. Votre programme s'arrêtera en vous affichant le message "toto.txt n'existe pas !". Vous pourrez bien sûr utiliser aussi la variable $! qui marque l'erreur émanant du système. Dans le cas où tout se passe bien à l'ouverture du handle, le programme affichera sur la sortie standard le contenu du fichier toto.txt. Mais, vous pouvez aussi faire en sorte d'afficher votre message d'erreur sans pour autant arrêter votre programme Perl. En utilisant la close warn, vous produirez le message d'erreur de votre choix sans que le script ne s'arrête :

Code perl : Sélectionner tout
open FILE, "< toto.txt" or warn "toto.txt n'existe pas !\n";

Mis à jour le 8 mai 2005 GLDavid

Perl vous autorise à avoir accès au moindre renseignement de vos fichiers. Le tableau suivant résume les différents tests possibles en Perl sur les fichiers :

Syntaxe Signification Remarque
-r Le fichier est lisible par l'uid et le gid effectifs Spécifique à Unix
-w Le fichier peut être écrit par l'uid et le gid effectifs Spécifique à Unix
-x Le fichier peut être exécuté par l'uid et le gid effectifs Spécifique à Unix
-R Le fichier est lisible par l'uid et le gid réels Spécifique à Unix
-W Le fichier peut être écrit par l'uid et le gid réels Spécifique à Unix
-X Le fichier peut être exécuté par l'uid et le gid réels Spécifique à Unix
-o Le fichier appartient à l'uid effectif Spécifique à Unix
-O Le fichier appartient à l'uid réel Spécifique à Unix
-e Le fichier existe
-z Le fichier existe et a une taille de 0
-s Le fichier existe et a une taille différente de 0 (retourne la taille)
-f Le fichier est un fichier ordinaire Spécifique à Unix
-d L'entrée est un répertoire
-l L'entrée est un lien symbolique Spécifique à Unix
-S L'entrée est une socket Spécifique à Unix
-p L'entrée est un pipe nommé FIFO Spécifique à Unix
-b L'entrée est un fichier spécial de blocs (comme un périphérique montable) Spécifique à Unix
-c L'entrée est un fichier spécial de caractères (périphérique E/S) Spécifique à Unix
-u Le bit setuid est activé pour ce fichier Spécifique à Unix
-g Le bit setgid est activé pour ce fichier Spécifique à Unix
-k Le sticky bit est activé pour ce fichier Spécifique à Unix
-t Le handle de fichier (défaut STDIN) est ouvert sur une tty Spécifique à Unix
-T Le fichier est un fichier texte. Retourne vrai pour un fichier vide ou pour un handle de fichier en fin de fichier (EOF)
-B Le fichier est un fichier non texte (binaire). Retourne vrai pour un fichier vide ou pour un handle de fichier en fin de fichier (EOF)
-M Date de la dernière modification exprimée en jours (avec décimale). La valeur retournée correspond à l'âge de fichier au moment du démarrage du programme
-A Date d'accès exprimée en jours (avec décimale). La valeur retournée correspond à l'âge de fichier au moment du démarrage du programme
-C Date de changement exprimée en jours (avec décimale). La valeur retournée correspond à l'âge de fichier au moment du démarrage du programme
Apprenez-le par coeur ! Interro surprise la semaine prochaine ! A l'aide de ces tests, on peut, par exemple, tester l'existence d'un fichier avant de l'ouvrir :

Code perl : Sélectionner tout
1
2
3
4
$file = "/home/gldavid/toto.txt"; 
if ( -e $file ) { 
  OPEN FILE, "< $file" or die "Un problème est survenu pendant l'ouverture du fichier !\n"; 
}
Ou bien, supprimer un fichier si celui-ci a une date de modification supérieure à 15 jours :

Code perl : Sélectionner tout
1
2
3
4
5
6
7
$file = '/home/gldavid/toto.txt'; 
OPEN FILE, "< $file" or die "Un problème est survenu pendant l'ouverture du fichier !\n"; 
if ( -M FILE > 15 ) { 
  close FILE; 
  unlink $file; 
  print "$file supprimé\n"; 
}
Depuis la version 5.10 de perl, il est possible d'empiler les tests sur un fichier. Voici un exemple

Code perl : Sélectionner tout
1
2
my $fichier = "/home/djibril/fichier.txt"; 
if ( -e -f $fichier ) { print "Le fichier $fichier existe"; }
Le code ci-dessus vérifie que $fichier existe et soit un fichier.

Toutefois, les informations sur les fichiers peuvent être aussi accessibles à l'aide des fonctions stat et lstat. Pour simplifier, stat ne concerne que les fichiers, lstat vous renseignera plus en détail pour des liens symboliques. La fonction stat vous renvoie au total treize informations que l'on peut rassembler soit à l'aide de treize variables scalaires ou d'un tableau :

Code perl : Sélectionner tout
1
2
3
4
my $chemin = '/home/gldavid/toto.txt'; 
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $block) = stat $chemin; 
# L'équivalent serait : 
# @infos = stat $chemin;
Ainsi, ces informations sont :

$dev ou $infos[0] Le numéro de périphérique, de "device" du système de fichiers
$ino ou $infos[1] Numéro d'inode du fichier
$mode ou $infos[2] Ensemble des bits de permission du fichier (ex : 0755). Droits du fichier (type et permissions)
$nlink ou $infos[3] Nombre de liens durs du fichier
$uid ou $infos[4] Identification numérique de l'utilisateur propriétaire du fichier
$gid ou $infos[5] Identification numérique du groupe propriétaire du fichier
$rdev ou $infos[6] L'identificateur du "device" (fichiers spéciaux uniquement)
$size ou $infos[7] Taille totale du fichier en octets
$atime ou $infos[8] Date (en secondes) d'accès au fichier depuis l'origine des temps
$mtime ou $infos[9] Date (en secondes) de dernière modification du fichier depuis l'origine des temps
$ctime ou $infos[10] Date (en secondes) de dernière modification de l'inode (pas la date de création) du fichier depuis l'origine des temps
$blksize ou $infos[11] Taille de blocs préférée pour les E/S sur les fichiers, indication pour le système
$block ou $infos[12] Nombre de blocs réellement occupés du fichier

Petit rappel : lstat convient mieux pour les liens symboliques et renverra les mêmes informations que stat. Toutefois, si vous utilisez lstat sur un fichier, lstat renverra dans tous les cas les mêmes informations que stat.

  • Les inodes (contraction de "index" et "node"; en français : nœud d'index) sont des structures de données contenant des informations concernant les fichiers stockés dans certains systèmes de fichiers, ce sont le centre de tous les échanges entre le disque et la mémoire ;
  • set Group ID ;
  • Set User ID ;
  • Le sticky bit donne le droit de manier de façon plus subtile les droits d'écriture d'un fichier. En effet, un droit d'écriture signifie que l'on peut modifier et supprimer le fichier. Le sticky bit permet de faire la différence entre les deux.

Mis à jour le 8 mai 2005 djibril

Se déplacer dans une arborescence de répertoires sous Perl est tout aussi simple que dans un système Unix. Bien entendu, vous pourriez avoir recours à un appel système mais Perl vous fournit la commande vous permettant de vous déplacer où bon vous semble

Code perl : Sélectionner tout
1
2
3
$chemin = '/home/gldavid/documents'; 
chdir $chemin; 
chdir '/home/2Eurocents/ultra_secrets';

Mis à jour le 8 mai 2005 GLDavid

Ouvrir un répertoire n'est pas plus difficile que d'ouvrir un fichier. Encore une fois, nous aurons recours au handle, ces précieux médias de communication entre votre programme Perl et vos fichiers/répertoires. Mais, tout comme les handles de fichiers, n'oubliez jamais de fermer vos handles de répertoires :

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
my ( $nbrep, $nbfic, $fichier, $dossier ) = ( 0, 0, undef, '/home/gldavid/perl' ); 
opendir my $dir, $dossier or die "$dossier n'existe pas !"; 
my @files = readdir $dir; 
foreach $fichier (@files) { 
  if ( -f "$dossier/$fichier" ) { $nbfic++; } 
  if ( -d "$dossier/$fichier" ) { $nbrep++; } 
} 
closedir $dir; 
print "Il y a $nbfic fichier(s) et $nbrep répertoire(s) dans $dossier.\n";
Ce programme permet de compter le nombre de fichiers et de répertoires contenus dans le répertoire /home/gldavid/perl.
Avec l'instruction opendir, nous ouvrons notre handle DIR sur ce répertoire. Si celui-ci n'existe pas, le programme se termine avec un message d'erreur décrit dans la clause die. Si tout se déroule bien, la fonction readdir va rassembler dans le tableau files tous les fichiers/répertoires contenus dans notre répertoire d'étude. Remarquez que readdir accepte le nom de votre handle. Dans la boucle foreach, nous testons pour chacun des fichiers si celui-ci est un fichier (auquel cas, la variable $nbfic est incrémentée) ou un répertoire (la variable $nbrep est incrémentée). A la fin de cette boucle, nous affichons le nombre de fichiers et de répertoires contenus dans /home/gldavid/perl.

Mis à jour le 8 mai 2005 GLDavid

Perl vous donne une fonction qui vous permettra d'effacer un fichier, pourvu que vous en soyez propriétaire :

Code perl : Sélectionner tout
1
2
3
$fichier = "/home/gldavid/toto.txt"; 
unlink $fichier; 
unlink '/home/gldavid/secrets_gnux/faq.html';
La fonction unlink vous permet d'effacer un ou plusieurs fichiers car unlink prend en argument une liste de fichier.

Code perl : Sélectionner tout
1
2
3
unlink $fichiers; 
unlink $fichier1, $fichier2, $fichier3; 
unlink glob '*.mp3';
L'utilisation de la clause glob avec le motif "*.mp3" fera que la fonction unlink effacera tous les fichiers portant l'extension .mp3 du répertoire /home/gldavid/MP3.

Mis à jour le 8 mai 2005 djibril GLDavid

Etes-vous anglophone ? Dans le domaine de l'informatique, cela peut vous être utile. En effet, pour renommer des fichiers, vous aurez recours à la fonction... rename !

Code perl : Sélectionner tout
1
2
3
4
$oldfile = '/home/gldavid/toto.txt'; 
$newfile = '/home/gldavid/tata.txt'; 
rename $oldfile, $newfile; 
rename '/home/gldavid/tata.txt', '/home/gldavid/titi.txt';

Mis à jour le 8 mai 2005 GLDavid

Les unixiens ne sont vraiment pas dépaysés avec Perl ! La création de répertoires nécessite l'appel de la fonction mkdir. Pour supprimer un répertoire, vous aurez naturellement recours à la fonction rmdir si votre répertoire cible est vide de tout fichier :

Code perl : Sélectionner tout
1
2
3
4
5
mkdir '/home/gldavid/dossier'; 
rmdir '/home/gldavid/dossier'; 
$dossier = '/home/gldavid/perl'; 
mkdir $dossier; 
rmdir $dossier;

Mis à jour le 8 mai 2005 djibril GLDavid

Au chapitre des commandes Unix se retrouvant dans Perl pour la gestion des fichiers, on retrouve notamment la commande chmod qui permet de modifier les permissions de lecture, écriture, exécution d'un fichier.

Code perl : Sélectionner tout
chmod 0755, "/home/gldavid/toto.txt";
Dans cet exemple, nous attribuons au fichier /home/david/toto.txt toutes les permissions pour l'utilisateur et les permissions de lecture/exécution pour le groupe et les autres. Attention, les permissions symboliques du type r+w ne sont pas permises. Un petit rappel de bon aloi :

  • la lecture a un poids de 4 ;
  • l'exécution a un poids de 1 ;
  • l'écriture un poids de 2.

De même, il est possible d'utiliser la fonction chown pour modifier le propriétaire du fichier :

Code perl : Sélectionner tout
chown "GLDavid", "root", /home/gnux/faq.html;
Cette commande Perl indique que le fichier /home/gnux/faq.html a comme nouveau propriétaire GLDavid du groupe root.

Mis à jour le 8 mai 2005 GLDavid

Depuis Perl 5.8, il est possible et recommandé d'ouvrir les fichiers d'une façon beaucoup plus propre et moins sujette à des erreurs :

  • utilisez des handles lexicaux (ou indirect) ;
  • utilisez la syntaxe open à trois arguments ou bien le module IO::File.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
my $fichier  = './MonFichier.txt'; 
my $fichier2 = './MonFichier2.txt'; 
  
# Lecture du fichier 
open my $FH, '<', $fichier or die "Impossible de lire $fichier"; 
  
#... 
#... 
close $FH or die "Impossible de fermer $fichier"; 
  
# Ecrire dans un fichier 
open my $FH2, '>', $fichier2 or die "Impossible d'écrire dans $fichier2"; 
print {$FH2} "Mon premier test\n"; 
close $FH2 or die "Impossible de lire $fichier2";
Autre méthode :

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use IO::File; 
  
my $fichier  = "./MonFichier.txt"; 
my $fichier2 = "./MonFichier2.txt"; 
  
# Lecture du fichier 
my $FH = new IO::File $fichier, '<' or die "Impossible de lire $fichier"; 
  
#... 
#... 
close $FH or die "Impossible d'écrire dans $fichier"; 
  
# Ecrire dans un fichier 
my $FH2 = new IO::File $fichier, '>' or die "Impossible d'écrire dans $fichier2"; 
print {$FH2} "Mon premier test\n"; 
close $FH2 or die "Impossible d'écrire dans $fichier2";

Mis à jour le 22 juillet 2007 djibril

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.

 
Responsable bénévole de la rubrique Perl : djibril -