SELFHTML/Aides à la navigation CGI/Perl Fonctions Perl |
Fonctions pour l'entrée/sortie et pour la lecture/écriture de données |
|
Généralités sur ces fonctions |
|
Pour Perl existent un canal d'entrée par défaut STDIN
- standard input et un canal de sortie par défaut STDOUT
- standard output. Un script Perl peut lire des données de STDIN
et sortir des données sur STDOUT
. En principe STDIN
est assimilé au clavier, c'est à dire que des entrées au clavier peuvent être lues de STDIN
. STDOUT
est par contre en principe assimilé à l'écran, c'est à dire que des sortie sur STDOUT
apparaissent à l'écran. Lors de l'utilisation d'un serveur Web avec un port CGI, cependant STDOUT
est "détourné" dans un fichier spécial que le serveur Web fait suivre au navigateur Web, et STDIN
pareillement dans un fichier dans lequel le serveur Web tient les données (par exemple les données d'un formulaire) à la disposition du script CGI appelé.
Outre STDOUT
il existe encore un autre canal spécial de sortie qui n'est conçu que pour les messages d'erreur, STDERR
. Dan un environnement normal de système d'exploitation STDERR
est en principe exactement comme STDOUT
la sortie à l'écran. Pour le port CGI d'un serveur Web, la sortie d'erreur standard STDERR
est dirigée par contre le plus souvent dans un fichier Log du serveur qui rassemble ce genre de messages d'erreur.
Les trois canaux représentent pour Perl ce qu'on appelle les Handles. À côté de ces canaux standard d'entrée et de sortie, vous pouvez en tant que programmeur ouvrir vos propres canaux d'entrée et de sortie. Ici, vous attribuez aussi vos propres noms pour les descripteurs. C' est indispensable par exemple quand vous voulez lire les données d'un fichier plutôt que du clavier ou quand vous voulez écrire dans un fichier plutôt qu'à l'écran. Pour pouvoir lire ou écrire dans un fichier, vous créez donc simplement un descripteur de fichier. Cela se passe à l'ouverture d'un fichier - pour cela sert avant tout la fonction open. Après que vous avez ouvert un fichier et que vous lui avez attribué un descripteur de fichier, vous avez accès à ce fichier par ce descripteur de fichier.
Perl propose différentes fonctions qui permettent d'accéder à des fichiers en lecture ou en écriture. Au descripteur de fichier s'ajoute par ailleurs un pointeur de fichier. Le pointeur de fichier sauvegarde à la lecture et à l'écriture la position de l'octet actuelle à l'intérieur du fichier. Vous pouvez rechercher la position du pointeur de fichier et fixer le pointeur de fichier sur une autre position, par exemple pour les fichiers avec certains formats de fichiers. De cette façon vous pouvez diriger exactement les processus de lecture et d'écriture.
Il y a des fonctions distinctes pour les répertoires - classeurs d'un système de fichiers. Vous pouvez de la même manière ouvrir un répertoire. Vous pouvez alors lire les éléments du répertoire, par exemple pour rechercher si des fichiers d'un certain type se trouvent dans le répertoire. Vous reconnaissez les fonctions pour les répertoires à ce que leur nom contient dir
. Ainsi par exemple open
ou seek
sont des fonctions de fichiers tandis que opendir
et seekdir
sont des fonctions de répertoires.
Outre les fonctions normales de lecture et d'écriture de fichier, existent aussi des variantes liées au système des fonctions correspondantes. N'utilisez cependant ces fonctions que si vous avez une raison particulière pour le faire! Vous reconnaissez ce genre de fonctions à ce que leur nom contient sys
. Alors par exemple que read
est une fonction normale de lecture, sysread
est la variante correspondante liée au système de cette fonction.
Les scripts Perl, que vous mettez en œuvre comme scripts CGI, peuvent à l'aide de ces fonctions lire et écrire des fichiers sur l'ordinateur serveur. Vous n'avez pas accès avec ces fonctions au système de fichiers d'un ordinateur client éloigné dont le navigateur Web qui y tourne a réclamé des données du serveur Web!
Il est important pour lire ou écrire correctement des fichiers binaires (par exemple des fichiers graphiques) que le système d'exploitation sous lequel tourne le script, fasse la distinction entre les fichiers texte et les fichiers binaires. Unix ne fait pas cette distinction, la fonction binmode
est donc sans objet pour les scripts Perl sous Unix. MS-DOS et MS-Windows par contre font la distinction entre le mode texte et le mode binaire.
Pour les fichiers non binaires, donc pour des fichiers en texte clair, les deux caractères de contrôle qui se suivent CR (Carriage Return) et LF (Line Feed) sont résumés automatiquement à la lecture d'un fichier en un LF sous des systèmes d'exploitation tels que DOS/Windows. À l'écriture d'un fichier texte, chaque LF est à nouveau transformé automatiquement en deux caractères CR et LF .
À l'appel de la fonction binmode
vous "éteignez" cet automatisme. Vous empêchez ainsi que l'automatisme accède à des endroits où il ne devrait pas accéder, par exemple quand vous lisez des données sauvegardées en numérique et qui contiennent par hasard deux octets de suite dont les valeurs correspondent aux valeurs des caractères pour CR et LF.
Attend comme paramètre:
1. le descripteur (handle) d'un canal d'entrée ou de sortie.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $nombre_octets = -s "/usr/web/src/ship.gif"; my $memoire; open(GRAPHIQUE, "</usr/web/src/ship.gif"); binmode(GRAPHIQUE); my $octets_lus = read(GRAPHIQUE, $memoire, $nombre_octets); close(GRAPHIQUE); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; print "<h1>le contenu du fichier comme bouillie de caractères:</h1>\n"; print "<p><tt>$memoire</tt></p>"; print "</body></html>\n"; |
L'exemple lit un fichier GIF binaire. Pour ce faire, le fichier est ouvert avec open. Ensuite, la fonction binmode
est appelée avec le descripteur de fichier du fichier ouvert (GRAPHIQUE
). Ensuite, le fichier est lu avec la fonction read.
À des fins de test, du code HTML est envoyé au navigateur appelant et représente le contenu du graphique comme une bouillie de caractères. Le contenu lu se trouve après lecture dans la scalaire $memoire
.
D'autres détails sur la lecture de fichiers binaires sont décrits avec la fonction read.
L'expression utilisée -s
pour fixer la taille du fichier sauvegardée dans $nombre_octets
, fait partie d'une série d'expressions similaires qui permettent la recherche de caractéristiques d'un fichier. D'autres détails à ce sujet dans la partie sur opérateurs de test fichier pour fichiers et répertoires
.
Ferme un fichier qui a été ouvert auparavant avec open.
Attend comme paramètre:
1. le descripteur d'un canal d'entrée ou de sortie ouvert, qui doit être fermé.
Un exemple complet avec explications des deux fonctions interdépendantes open
et close
est traité avec la fonction open!
Quand vous ne fermez pas explicitement un fichier ouvert auparavant avec close
, le fichier est automatiquement fermé par Perl à la fin du script.
ferme un descripteur de répertoire qui a été ouvert auparavant avec opendir.
Attend comme paramètre:
1. le descripteur de répertoire.
Un exemple complet avec explications des deux fonctions interdépendantes opendir
, readdir
et closedir
est traité avec la fonction opendir!
Demande à un fichier ouvert si le pointeur de fichier a atteint la fin du fichier.
Attend comme paramètre:
1. le descripteur d'un canal d'entrée ou de sortie.
Renvoie true
si la fin du fichier est atteinte, et false
, si ce n'est pas le cas.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $max = 100000; my $i = 0; my $etat = 0; print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title>\n"; print "</head><body>\n"; open(FICHIER, "</usr/chatlog/lastnight.txt"); while(1) { if(eof(FICHIER)) { $etat = 1; last; } if($i > $max) { $etat = 2; last; } getc(FICHIER); $i++; } close(FICHIER); if($etat == 1) { print "<p>Le fichier a moins de $max octets, et a donc été lu entièrement</p>\n"; } if($etat == 2) { print "<p>Le fichier était trop grand, n'ont donc été lus que $max octets</p>\n"; } print "</body></html>\n"; |
L'exemple génère du code HTML pour le navigateur appelant. Ici un fichier texte /usr/chatlog/lastnight.txt
est ouvert avec la fonction open. Le fichier ouvert est lu dans une boucle while signe par signe avec la fonction getc. Étant donné que la condition de la boucle (1)
est toujours vraie, des conditions d'interruptions sont formulées à l'intérieur de celle-ci. Quand la fin du ficher est atteinte - if(eof(FICHIER))
- la scalaire $etat
est fixée à 1 et la boucle se termine par last
.
La boucle se termine également quand plus de signes qu'il n'est défini dans $max
ont été lus. Dans ce cas $etat
est fixé à 2.
En questionnant la valeur de $etat
il est possible d'établir à la fin de la boucle ce qui a occasionné l'interruption. En fonction de cela, une phrase correspondante est sortie.
if(eof(FICHIER))
("si la fin du fichier est atteinte") ou bien while(! eof(FICHIER))
("aussi longtemps que la fin du fichier n'est pas atteinte") sont des formulations typiques lors de la mise en œuvre de la fonction eof
. De telles requêtes et conditions de boucle sont indiquées avant tout quand vous lisez des fichiers caractère par caractère (avec la fonction getc
) ou bien par bloc (avec la fonction read).
Chaque canal d'entrée ou de sortie ouvert a en interne un numéro, même en ce qui concerne les canaux de sortie que vous n'avez pas ouvert vous même STDIN
, STDOUT
et STDERR
. Avec cette fonction, il vous est possible de rechercher le numéro interne d'un canal d'entrée ou de sortie.
Attend comme paramètre:
1. le descripteur d'un canal d'entrée ou de sortie.
Renvoie le numéro du canal d'entrée ou de sortie.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title>\n"; print "</head><body>\n"; open(FICHIER, "</usr/texte/important.txt"); my $fichier = fileno(FICHIER); close(FICHIER); my $entree = fileno(STDIN); my $sortie = fileno(STDOUT); my $erreur = fileno(STDERR); print "Entrée= $entree, Sortie = $sortie, Erreur = $erreur, Fichier = $fichier\n"; print "</body></html>\n"; |
L'exemple génère du code HTML pour le navigateur Web appelant. Ici un fichier texte /usr/texte/important.txt
est ouvert avec la fonction open. Avec fileno(FICHIER)
le numéro interne du descripteur de ce fichier est recherché et sauvegardé dans une scalaire $fichier
. De la même façon, les numéros internes des trois canaux standard sont recherchés et sauvegardés dans des scalaires correspondantes. Enfin, le script sort les numéros ainsi trouvés.
Règle comment d'autres processus peuvent accéder à un fichier pendant que le script actuel a ouvert le fichier. Pour des scripts CGI, ce peut être très important. Car pendant qu'un script appelé par le navigateur d'un utilisateur mène à bien son travail, un autre navigateur d'un autre utilisateur peut très bien appeler le même script. Les deux processus travaillent alors dans la mémoire de travail de l'ordinateur serveur et cela indépendamment l'un de l'autre, mais ils exécutent le même code et accèdent aux mêmes fichiers. Afin qu'un autre processus n'efface pas les données que le processus actuel vient juste d'écrire, il est possible pour le processus de protéger le fichier contre d'autres accès.
Important: Pour les systèmes d'exploitation qui n'ont en interne implémenté aucun flock
, l'application de cette fonction mène à une erreur, comme par exemple pour Windows 95/98!
Attend comme paramètre:
1. le descripteur du fichier ouvert.
2. le numéro de l'option de verrouillage ou une constante - sont permis les numéros 1
, 2
, 8
et 4
ou bien les constantes LOCK_SH
, LOCK_EX
, LOCK_UN
et LOCK_NB
:
Le numéro 1
ou la constante LOCK_SH
signifie shared (partager un fichier avec d'autres processus, par exemple quand un processus qui accède à un fichier en lecture ne doit pas gêner d'autres processus qui lisent le même fichier en même temps),
Le numéro 2
ou la constante LOCK_EX
signifie exclusive (ne permettre à aucun autre processus le moindre accès au fichier),
Le numéro 8
ou la constante LOCK_UN
signifie unlock (lever à nouveau expressément la protection d'accès).
Le numéro 4
ou la constante LOCK_NB
signifie non-blocking (uniquement en relation avec 1
ou bien 2
ou LOCK_SH
ou LOCK_EX
permet et met fin à une tentative d'accès au fichier au lieu d'attendre qu'un accès soit à nouveau possible).
Vous ne pouvez employer les constantes que si vous incorporez le module Fcntl
(voir l'exemple ci-dessous).
Renvoie true
si le procédé a été couronné de succès et false
, s'il ne l'a pas été.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); use Fcntl ':flock'; $| = 1; open(FICHIER_DONNEES, "</db/donnees.csv"); flock(FICHIER_DONNEES, LOCK_EX); # Supposons qu'il se passe ici quelque chose qui prenne du temps, # et qu'en même temps un autre processus tente d'accéder au fichier # puis accède au verrouillage flock(FICHIER_DONNEES, LOCK_UN); close(FICHIER_DONNEES); |
Si vous désirez utiliser des constantes à la place de numéros, vous devez noter d'abord une constante pour incorporer le module de verrouillage, par exemple comme sous la forme ci-dessus: use Fcntl ':flock';
Après que vous avez réussi à ouvrir un fichier et que vous avez un descripteur de fichier correspondant pour l'accès au fichier, vous pouvez fixer les options de verrouillage pour le fichier. C'est ce qui se passe dans l'exemple après l'appel de la fonction open à l'aide de l'instruction flock(FICHIER_DONNEES, LOCK_EX);
Ici le descripteur de fichier est FICHIER_DONNEES
, et la mention de verrouillage désirée est LOCK_EX
. Dans l'exemple, le fichier est verrouillé exclusivement. Aussi longtemps que le verrouillage à l'intérieur du script n'est pas levé ou que le fichier n'est pas fermé, aucun autre processus qui tient compte de flock
, ne peut écrire en même temps dans le fichier.
Les deux commandes
flock(FICHIER_DONNEES, LOCK_UN);
close(FICHIER_DONNEES);
ne servent dans le fichier ci-dessus qu'à une meilleure compréhension. La levée explicite du verrouillage est à vrai dire superflue, si elle ne doit intervenir qu'avec la fermeture du fichier avec la fonction close. Car close
lève en même temps toute mention de verrouillage de fichier.
L'instruction $| = 1;
de l'exemple ci-dessus sert à déconnecter la sortie dans la mémoire tampon (comparez à ce sujet avec les Variables prédéfinies en Perl). Elle est à recommander lors du verrouillage de fichiers. Car il peut arriver autrement que par la sortie différée en mémoire tampon l'écriture de données n'ait lieu que lorsque le verrouillage a déjà été levé. Ce qui rendrait vain l'objectif même du verrouillage.
Quand vous désirez travailler avec l'option de verrouillage 4
ou LOCK_NB
, vous devez relier cette option avec une option de verrouillage par une liaison par bit. Exemples:
flock(FICHIER_DONNEES, LOCK_EX | LOCK_NB);
flock(FICHIER_DONNEES, LOCK_SH | LOCK_NB);
Important: flock
n'impose aucun verrouillage, mais n'a qu'un caractère de recommandation. La protection d'accès n'est efficace que lorsque tous les processus qui accèdent au fichier tiennent compte de flock.
C'est une fonction puissante pour formater de façon éloquente des données pour la sortie sur un périphérique orienté sur le texte comme un écran texte ou une imprimante par ligne. Cette fonction n'a quasiment pas d'usage avec les scripts CGI étant donné qu'une minorité de navigateurs Web travaillent orientés caractères.
#!/usr/bin/perl -w use strict; my $nom = "Hagenor"; my $prenom = "Henriette"; my $ville = "Honfleur"; format STDOUT = @<<<<<<<<<<<<< @<<<<<<<<<<<<< de @<<<<<<<<<<<<< $prenom, $nom, $ville . write; |
Dans l'exemple 1 la sortie est la suivante:
Henriette Hagenor de Honfleur |
Le formatage de la sortie se fait par la construction format
. La sortie proprement dite se fait par la commande finale write
.
Lors de la construction pour le formatage, mentionnez derrière format
un nom pour le format, en principe le nom du descripteur de fichier désiré. En réalité, le nom n'est pas un descripteur de fichier, il n'en revêt que l'apparence. Le format par défaut pour un descripteur de fichier a somme toute le même nom que le descripteur de fichier. Dans l'exemple ci-dessus le nom de format mentionné est STDOUT
, parce que l'écriture doit se faire sur la sortie standard STDOUT
. Derrière le nom de format suit le signe égal.
Les lignes qui suivent ensuite se composent toujours de paires de lignes. D'abord sont notées une ou plusieurs lignes de formatage lignes de formatage(n), et ensuite, une ligne d'arguments. Dans la ligne de formatage, vous définissez à l'aide de signes symboliques spéciaux le format de sortie pour certains champs et dans la ligne d'arguments, les variables qui doivent être sortis dans les champs correspondants.
Avec un point (.) sur une ligne distincte la construction Format est terminée.
Pour la ligne de formatage prévalent les règles suivantes:
|
En plus de ces possibilités de formatage, il y a quelques variables prédéfinies en Perl, que vous pouvez utiliser pour la sortie.
#!/usr/bin/perl -w use strict; format STDOUT = page @<< @>>>>>>> $%, $~ . write; |
Dans l'exemple 2 la sortie est la suivante:
page 0 STDOUT |
Le formatage de la sortie se fait par la construction format
. À la place de variables banales, des variables spéciales prédéfinies sont sorties. Les variables spéciales suivantes sont possibles:
|
Pour des sorties plus longues, de fichiers par exemple, vous pouvez aussi utiliser des lignes d'entête. L'exemple suivant montre comment vous pouvez sortir un fichier:
#!/usr/bin/perl -w use strict; my $Zeile; open(FICHIER,"</usr/texte/donnees.txt"); format STDOUT_TOP = **************************************************** page @>> $% **************************************************** . format STDOUT = @<<<<<<<<<<<<<<< $ligne; . while(<FICHIER>) { chomp $_; $ligne = $_; write; } close(FICHIER); |
Dans l'exemple 3 sont sortis les 15 premiers caractères de chaque ligne d'un fichier texte imaginaire.
Le formatage de la sortie dans l'exemple 3 a lieu avec deux constructions format
. Les deux constructions reçoivent les noms STDOUT_TOP
et STDOUT
. Par la chaîne de caractères _TOP
à la fin d'un nom de format vous faites savoir à Perl qu'il s'agit d'une définition de ligne d'entête. Dans l'exemple, la ligne d'entête est formatée par deux lignes composées d'astérisques, avec entre elles le numéro de la page actuelle.
Dans la poursuite du déroulement de l'exemple 3 vous voyez comment le fichier est lu ligne par ligne dans une boucle while, ligne copiée dans une variable nommée $ligne
. Cette variable est sortie à chaque fois - ici aussi dans la boucle. Le formatage de la sortie est assuré par la construction Format nommée STDOUT
. Là la variable $ligne
est sortie sous la forme souhaitée.
Lit un signe d'un fichier ouvert précédemment et positionne le pointeur de fichier un caractère plus loin.
Attend comme paramètre:
1. le descripteur de fichier.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title>\n"; print "</head><body><pre>\n"; open(FICHIER, "</usr/texte/important.txt"); my $octets = 0; while(! eof(FICHIER)) { my $signe = getc(FICHIER); print "$signe"; $octets++; } close(FICHIER); print "</pre><b>$octets caractères lus!</b>\n"; print "</body></html>\n"; |
L'exemple génère du code HTML pour le navigateur appelant. Ici aussi un fichier texte /usr/texte/important.txt
est ouvert avec la fonction open . Le fichier ouvert est lu signe par signe dans une boucle while jusqu'à ce que la fin du fichier soit atteinte, ce qui est demandé avec la fonction eof. Les caractères lus sont sortis. Par ailleurs, la scalaire $octets
est incrémentée de 1 à chaque signe lu. De cette façon, le nombre des caractères lus est recherché parallèlement. À la fin, ce nombre est aussi sorti.
Ouvre un fichier pour la lecture et/ou pour l'écriture ou aussi pour l'exécution. Les fichiers binaires sont aussi ouverts avec cette fonction.
Attend comme paramètre:
1. le nom du descripteur de fichier (pouvant être choisi librement), et
2. le nom de chemin du fichier à ouvrir, soit comme mention de chemin absolue ou comme mention de chemin relative par rapport au répertoire actuel (si le répertoire actuel n'est pas connu, il est recommandé de changer pour un répertoire déterminé à l'aide de la fonction chdir). Comme signe de séparation entre les répertoires dans le chemin, vous pouvez utiliser la barre oblique normale, même si le script doit tourner sur un ordinateur Windows/DOS. Perl transforme cette syntaxe en interne d'après l'environnement de l'installation.
Vous ne pouvez cependant pas mentionner d'URI!
Juste avant le nom (de chemin) du fichier à ouvrir, notez par ailleurs à l'aide des signes <
, >
et |
comment le fichier doit être ouvert. Si vous ne faites aucune de ces mentions, le fichier n'est ouvert qu'en lecture. Les mentions suivantes sont permises:
<fichier.dat
signifie: ouvrir le fichier fichier.dat
en lecture seule. Le fichier doit exister, sinon il y a une erreur.
>fichier.dat
signifie: ouvrir le fichier fichier.dat
pour l'écriture de données. Si le fichier existe déjà, son contenu est écrasé. Si le fichier n'existe pas encore, il est créé automatiquement.
>>fichier.dat
signifie: ouvrir le fichier fichier.dat
pour l'écriture de données. Si le fichier existe déjà, le nouveau contenu est ajouté à l'ancien contenu, ce qui veut dire que l'ancien contenu n'est pas effacé. Si le fichier n'existe pas encore, il est créé automatiquement.
+>fichier.dat
signifie: ouvrir le fichier fichier.dat
pour la lecture et l'écriture de données.
|fichier
signifie: Le fichier fichier
est un fichier programme exécutable ou une commande de console. Le programme ou la commande sont exécutées. Du point de vue de Unix, un opérateur de dérivation de données est ouvert vers le programme ou la commande.
fichier|
signifie: Le fichier fichier
est un fichier programme exécutable ou une commande de console. Le programme ou la commande sont exécutées. Du point de vue de Unix, un opérateur de dérivation de données est ouvert à partir du programme ou la commande.
Quand le fichier peut être ouvert, la fonction open
renvoie la valeur true
, sinon la valeur undef
.
#!/usr/bin/perl -w use strict; open(FICHIER, "</tmp/server.cfg") || die "Fichier non trouvé"; my @lignes = <FICHIER>; close(FICHIER); my @nouvelles_lignes; foreach(@lignes) { $_ =~ s/#.*//; push(@nouvelles_lignes,$_) if $_ !~ /^\s*\n/; } open(FICHIER, ">/tmp/server.cfg") || die "Fichier non trouvé"; print FICHIER @nouvelles_lignes; close(FICHIER); |
L'exemple montre comment ouvrir un fichier, le lire, le traiter et le fermer, puis l'ouvrir à nouveau pour y écrire les données venant d'être traitées. Il s'agit ici d'un fichier de configuration imaginaire dans lequel beaucoup de lignes contiennent des commentaires placés derrière la commande de configuration proprement dite et qui commencent par #
. Dans l'exemple, le fichier est traité de telle façon que ces lignes de commentaires sont effacées.
Tout d'abord la fonction open
est appelée. Ici le fichier désiré est ouvert en lecture. Le fichier est ensuite copié dans la liste @lignes
(dans chaque élément de @lignes
figure à la fin une ligne du fichier). Après la lecture et la copie, le fichier est refermé avec close.
Ces trois commandes pour ouvrir, lire et copier et fermer sont typiques.
Dans l'exemple ci-dessus, les lignes lues sont traitées ensuite dans l'ordre dans une boucle foreach. Ici la partie commentaires de chaque ligne est effacée. Cela s'obtient dans l' expression régulière pour rechercher/remplacer (s/#.*//g
). Ensuite, la ligne traitée actuelle est ajoutée à la liste @nouvelles_lignes
avec push - mais seulement si la ligne contient autre chose que des espaces suivis d'un caractère de contrôle de passage à la ligne. Pour cela aussi une expression régulière appropriée est a nouveau appliquée.
Enfin, le fichier est à nouveau ouvert, cette fois néanmoins en écriture ou plus précisément: pour écraser le contenu antérieur. À l'aide de la fonction print la liste @nouvelles_lignes
est écrite dans le fichier. À la fin, le fichier est fermé.
Si des erreurs surviennent à l'ouverture de fichiers importants, il est le plus souvent judicieux de mettre fin aussitôt au script. C'est à cela que sert la fonction die, qui est aussi utilisée dans l'exemple ci-dessus.
Dans la plupart des cas, il est judicieux de refermer un fichier ouvert dès que vous n'avez plus À y lire ou à y écrire. Cela permet de libérer des ressources du système d'exploitation et permet aussi à d'autres programmes ou processus d'accéder à nouveau au fichier si vous aviez auparavant verrouillé ce fichier.
Ouvre un répertoire par exemple pour qu'il soit lu. Ici vous attribuez un descripteur de fichier par lequel vous pouvez accéder au répertoire.
Attend comme paramètre:
1. le nom du descripteur de répertoire (pouvant être choisi librement), et
2. le nom de chemin du répertoire à ouvrir, soit comme mention de chemin absolue ou comme mention de chemin relative par rapport au répertoire actuel (si le répertoire actuel n'est pas connu, il est recommandé de changer pour un répertoire déterminé à l'aide de la fonction chdir.
Renvoie TRUE
quand le répertoire a pu être ouvert. Quand une erreur est survenue, celle-ci est sauvegardée dans la variable $!
.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $repertoire = "/donnees/web"; opendir(DIR, $repertoire) || die "$repertoire: $!"; my @enregistrements = readdir(DIR); closedir(DIR); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; foreach(@enregistrements) { print "$_<br>\n"; } print "</body></html>\n"; |
Dans l'exemple, le chemin d'un répertoire ("/donnees/web"
) est sauvegardé dans la scalaire $repertoire
. Observez que les répertoires du chemin sont séparés par des barres obliques simples et non pas par des barres obliques inversées comme c'est habituel sous DOS/Windows. Utilisez la syntaxe avec les barres obliques même si Perl tourne chez vous sous DOS/Windows. Quand vous désirez adresser un autre disque que le disque actuel dans un environnement DOS/Windows, Faites précéder simplement la mention de la lettre du disque suivie de deux points, donc par exemple c:/temp
.
Avec la fonction opendir
le répertoire est ouvert. DIR
est un nom attribué personnellement au descripteur de répertoire. De plus, la fonction reçoit comme paramètre la scalaire dans laquelle le répertoire désiré est sauvegardé. Au cas où le répertoire ne peut pas être ouvert, le script se termine par l'appel de la fonction die.
L'exemple ci-dessus utilise le répertoire ouvert pour copier le contenu du répertoire dans une liste @enregistrements
à l'aide de la fonction readdir. Ensuite, le répertoire est fermé par l'appel de la fonction closedir. L'exemple envoie ensuite du code HTML au navigateur appelant. Ici la liste des enregistrements du répertoire est sortie.
Tous les enregistrements du répertoire sont sortis, à savoir les noms de fichiers mais aussi les noms de sous-répertoires, ainsi que les noms de répertoires "symboliques" que l'on trouve sur la plupart des systèmes avec un point (.
) (représente le répertoire actuel) et deux points (..
) (représente le répertoire parent).
Écrit les données sur la sortie standard ou dans un canal de sortie ouvert, donc par exemple un fichier. Les données peuvent être une chaîne de caractères distincte ou une liste de chaînes de caractères. Dans ces chaînes de caractères peuvent aussi être placées des variables, donc des scalaires distinctes, mais aussi des listes complètes ou des hashes. Perl reconnaît les variables et écrit leur valeur à l'endroit correspondant.
Cette fonction est très souvent employée dans des scripts CGI pour envoyer du code HTML au navigateur.
Attend comme paramètre:
1. le descripteur de fichier = mention facultative sur le canal de sortie. Si vous omettez cette mention, l'écriture se fait sur la sortie standard STDOUT
. Quand vous avez ouvert un fichier avec open et que vous voulez écrire dans celui-ci, vous devez mentionner le descripteur de fichier attribué avec open
.
2. donnees[,donnees] = un ou plusieurs éléments (chaînes de caractères, nombres etc...) qui doivent être écrits.
Renvoie true
si Perl a pu écrire les données avec succès.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; print "<table border=\"1\">\n","<tr><td><b>variable d'environnement</b></td><td><b>valeur actuelle</b></td></tr>\n"; my $i = 0; my $enregistrement; foreach $enregistrement (%ENV) { if($i == 0) { print "<tr><td>$enregistrement</td>\n"; } else { print "<td>$enregistrement</td></tr>\n"; } if($i == 0) { $i = 1; } else { $i = 0; } } print "</table>\n","</body></html>\n"; |
L'exemple sort toutes les variables d'environnement CGI du serveur Web et cela proprement formaté dans un tableau HTML. Pour ce faire les éléments du hash prédéfini %ENV
sont traités dans une
boucle foreach et sont écrits dans le tableau HTML. Les sorties HTML correspondantes sont écrites à l'aide de commandes print.
Dans la dernière des commandes print
vous pouvez voir comment il est possible de noter plusieurs chaînes de caractères à la suite en les séparant par des virgules.
Dans les commandes print
à l'intérieur de la boucle, vous pouvez voir comment une variable (dans l'exemple la scalaire $enregistrement
) est notée au milieu d'une chaîne de caractères à sortir. À l'endroit correspondant la valeur respectivement actuelle de $enregistrement
est sortie.
Quand vous devez noter de nombreuses commandes print
à la suite, vous pouvez aussi adopter une solution plus lisible:
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print <<"FIN"; <html> <head> <title>Titre</title> </head> <body bgcolor="#FFFFCC"> <h1>HTML tout à fait normal</h1> <p>Perl et HTML sont quelquefois comme Adam et Ève</p> </body> </html> FIN |
Vous pouvez sortir des sections de texte plus importantes, par exemple le code HTML complet en un seul bloc. Pour ce faire notez derrière la commande print
deux <<
suivis immédiatement (sans espace qui sépare) du nom d'un délimiteur de fin jusqu'auquel tout doit simplement être sorti comme du texte. Derrière le nom du délimiteur de texte, dans la ligne de la commande print
notez le point-virgule habituel. À la fin du texte à sortir, notez sur une ligne distincte le nom du délimiteur de fin, ici cependant sans point-virgule à la fin. Il s'est instauré d'utiliser des majuscules pour ces noms d'étiquettes, parce qu'ainsi, les étiquettes sont mieux visibles dans le texte source.
Avec des scripts CGI le contenu des données sorties peut aussi être interprété comme commande HTTP. L'instruction:
print "Content-type: text/html\n\n";
en est un exemple typique. Ici un simple entête HTTP, indispensable pour la communication entre le serveur et le navigateur, est envoyé. Une autre variante intéressante pour les scripts CGI est l'instruction suivante (exemple):
print "Location: http://actuel.fr.selfhtml.org/\n\n";
Ici aussi un entête HTTP est sorti qui assure un suivi à l'URI mentionnée. Un script CGI qui comprend une telle instruction Location
, n'a pas besoin, sinon, d'envoyer d'autre code HTML au navigateur.
Écrit des données sur la sortie standard ou sur la canal de sortie ouvert, donc par exemple dans un fichier. Cette fonction sert à sortir des éléments de données distincts formatés. Ainsi par exemple des nombres décimaux peuvent-ils être sortis sous leur forme hexadécimale sans beaucoup de transcription, ou la sortie de nombres à virgule flottante avec de nombreuses position après la virgule peut être tronquée à un certain nombre de positions après la virgule.
La fonction printf en Perl correspond pour l'essentiel à la fonction printf en C.
Attend comme paramètre:
1. le descripteur de fichier = mention facultative sur le canal de sortie. Si vous omettez cette mention, l'écriture se fait sur la sortie standard STDOUT. Quand vous avez ouvert un fichier avec open et que vous voulez écrire dans celui-ci, vous devez mentionner le descripteur de fichier attribué avec open
.
2. la chaîne de format = une chaîne de caractères qui peut contenir des indicateurs de format pour certains éléments à sortir et cela conformément à la syntaxe spéciale de la fonction printf (syntaxe du signe %).
3. la liste de sortie = un ou plusieurs élément qui se réfèrent aux indicateurs de format spéciaux de la chaîne de format.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $montant_brut = 27.95; my $montant_net = $montant_brut / 1.16; print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; printf "Le montant net contenu dans le montant brut %s s'élève sans être arrondi à %.2f", $montant_brut, $montant_net; print "</body></html>\n"; |
L'exemple sort à l'aide de la fonction printf
les deux variables $montant_brut
et $montant_net
. La valeur de $montant_net
est calculée et représente un nombre fractionné avec de nombreuses positions après la virgule. Dans la sortie avec printf
cependant ce nombre est limité à deux positions après la virgule.
Pour cela, notez dans la chaîne de caractères à sortir un indicateur de format à l'endroit désiré. Ces indicateurs de format commencent par le signe pourcentage %
suivi des mentions pour le formatage. Le tableau suivant dresse la liste des indicateurs de format possibles et de leurs possibilités de formatage.
|
En plus de ces indicateurs de format, vous disposez également de ce qu'on appelle des drapeaux à l'aide desquels le sortie peut être ajustée encore plus finement. Les drapeaux doivent être notés immédiatement derrière le signe pourcentage de l'indicateur de format. Le tableau suivant dresse la liste des drapeaux possibles:
|
lit dans un ficher et copie dans une scalaire un nombre de caractères à mentionner et ce à partir de la position actuelle du pointeur de fichier.
Attend comme paramètre:
1. le descripteur de fichier.
2. une scalaire dans laquelle les signes lus sont sauvegardés.
3. le nombre de signes à y copier.
4. (facultatif) décalage (offset) - quand les signes qui doivent être copiés dans la scalaire chaîne de caractères (2.) ne doivent pas commencer au premier caractère mais à partir d'un caractère n, qui est mentionné comme Offset (le comptage commence à 0).
Renvoie le nombre de caractères lus. Quand la fin du fichier a été atteinte 0
est renvoyé. Quand une erreur survient, undef
est renvoyé.
[Sat Feb 03 17:24:44 2001] [error] [client 127.0.0.1] File does not exist: /usr/web/src/formate.css |
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title>\n"; print "</head><body>\n"; my $sortie; open(FICHIER_ERREURS, "</usr/logs/error.log") || die "fichier Log non trouvé!"; my $caracteres_lus = read(FICHIER_ERREURS, $sortie, 26); close(FICHIER_ERREURS); print "caractères lus: $caracteres_lus; Contenu lu: $sortie\n"; print "</body></html>\n"; |
L'exemple montre dans la première partie le contenu d'un fichier nommé error.log. Le fichier contient une ligne dans laquelle une erreur est recensée. Dans la deuxième partie de l'exemple, un script CGI lit ce fichier mais pas complètement, mais seulement 26 caractères. Étant donné que le pointeur de fichier après l'ouverture de fichier avec open est placé sur 0, la commande read
notée dans l'exemple lit les 26 premiers caractères du fichier. Pour le contrôle le script dans l'exemple sort le nombre de signes lus, qu'il recherche par la valeur retournée par read
dans la scalaire $caracteres_lus
. De plus, le script sort la chaîne de caractères lus. Dans l'exemple c'est exactement la partie qui marque la date dans le fichier error.log, à savoir [Sat Feb 03 17:24:44 2001]
. Ce sont les 26 premiers caractères.
Pour placer le pointeur de fichier à un autre endroit avant la lecture avec read
, vous pouvez utiliser la fonction seek.
Lit les éléments d'un répertoire qui a été ouvert auparavant avec la fonction opendir.
Attend comme paramètre:
1. le descripteur de répertoire qui a été attribué quand le répertoire a été ouvert avec opendir
.
Renvoie l'élément suivant du répertoire quand la valeur renvoyée est sauvegardée dans une scalaire, par exemple:
$enregistrement = readdir(DIR);
Renvoie tous les éléments du répertoire quand la valeur renvoyée est sauvegardée dans une liste, par exemple:
@enregistrements = readdir(DIR);
Les éléments du répertoire sont des fichiers visibles, des répertoires ainsi que des caractères de remplacement pour le répertoire actuel (.
) et pour le répertoire parent (..
).
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $repertoire = "/usr/web/ars_vivendi"; my $repertoire_URI = "/ars_vivendi"; opendir(DIR, $repertoire) || die "$repertoire: $!"; my @fichiers = readdir(DIR); closedir(DIR); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; foreach(@fichiers) { if($_ =~ /.+\.htm*/) { print "<a href=\"$repertoire_URI/$_\">$repertoire_URI/$_</a><br>\n"; } } print "</body></html>\n"; |
Dans l'exemple le chemin d'un répertoire ("/usr/web/ars_vivendi"
) est sauvegardé dans la scalaire $repertoire
. Dans une deuxième scalaire $repertoire_URI
un deuxième chemin ("/ars_vivendi"
) est sauvegardé. La raison en est que dans l'exemple "/usr/web"
est le répertoire racine (document root) du serveur Web installé. Alors "/ars_vivendi"
est un répertoire enfant de la racine du document.
Un répertoire est ouvert avec la fonction opendir
. Le contenu du répertoire est copié dans une liste @fichiers
à l'aide de readdir
. Finalement, le répertoire est fermé par l'appel de la fonction closedir.
L'exemple envoie ensuite du code HTML à un navigateur appelant. Ici la liste des éléments du répertoire est analysée. Les éléments dans lesquels on trouve le modèle de recherche .+\.htm*
, sont sortis ligne par ligne, et cela encadrés par des marquages HTML, qui font que chaque élément peut être cliqué en tant que lien. Pour l'adressage correct du nom de fichier HTML pouvant être cliqué, on utilise la scalaire $repertoire_URI
.
Positionne à nouveau le pointeur de lecture sur le premier élément dans un répertoire qui a été ouvert auparavant avec la fonction opendir. Cela peut être judicieux quand vous avez déjà lu le répertoire avec readdir, et que vous désirez employer le descripteur de répertoire pour une nouvelle lecture du contenu du répertoire.
Attend comme paramètre:
1. le descripteur de répertoire qui a été attribué quand le répertoire a été ouvert avec opendir
.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $repertoire = "/usr/work"; print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; opendir(DIR, $repertoire) || die "$repertoire: $!"; my @enregistrements = readdir(DIR); my $enregistrement; foreach $enregistrement (@enregistrements) { if($enregistrement =~ /.+\.bak/) { unlink($repertoire."/".$enregistrement); } } rewinddir(DIR); @enregistrements = ""; @enregistrements = readdir(DIR); foreach $enregistrement (@enregistrements) { print "$enregistrement<br>\n"; } print "</body></html>\n"; closedir(DIR); |
L'exemple lit tout d'abord tous les éléments d'un répertoire $repertoire
et les copie dans la liste @enregistrements
. Cette liste est ensuite parcourue à la recherche de fichiers du type *.bak (extension de fichier typique pour les fichiers de sauvegarde). Dans l'exemple, les fichiers avec cette extension sont effacés (avec unlink). Quand cette action est terminée, le pointeur de répertoire est ré-initialisé avec rewinddir(DIR)
, car le répertoire avec le même descripteur de fichier DIR
toujours ouvert, doit maintenant encore être lu. Lors de la deuxième lecture tous les éléments existants sont sortis. Les fichiers du type *.bak ne doivent à vrai dire plus y être. Souvent cependant la nouvelle lecture a lieu avant que les fichiers ne soient effacés par le système d'exploitation, et c'est la raison pour laquelle les anciens éléments sont malgré tout sortis.
Positionne le pointeur de fichier d'un descripteur de fichier qui a été créé auparavant avec open, à un endroit quelconque dans le fichier.
Attend comme paramètre:
1. . le descripteur du fichier ouvert.
2. position de l'octet dans le fichier, en fonction de la position de référence mentionnée dans le troisième paramètre
3. position de référence pour la mention dans le deuxième paramètre. Celle-ci peut avoir les valeurs 0, 1 ou 2:
0 signifie calculée de façon absolue à partir du début du fichier (position 0,
1 signifie calculée de façon relative à partir de la position actuelle du pointeur de fichier,
2 signifie calculée de façon absolue à partir de la fin du fichier (normalement la mention du deuxième paramètre doit être dans ce cas un nombre négatif).
ISBN 3-7723-7514-6 |
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $fichier = "isbn.txt"; my $numero_ISBN; open(FICHIER, "<$fichier"); seek(FICHIER, 5, 0); read(FICHIER, $numero_ISBN, 13); close(FICHIER); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title>\n"; print "Numéro ISBN: $numero_ISBN"; print "</body></html>\n"; |
L'exemple montre dans la première partie le contenu d'un fichier nommé isbn.txt. Le fichier contient une ligne dans laquelle est noté un numéro ISBN, et où le numéro ISBN proprement-dit ne commence cependant qu'à la position 5. Dans la deuxième partie de l'exemple, un script CGI lit ce fichier mais pas complètement, à partir de la position 5 seulement et à partir de là 13 signes.
Étant donné qu'à l'ouverture du fichier avec open le pointeur de fichier est positionné sur 0, il est placé sur la position 5 à partir du début avec seek(FICHIER, 5, 0)
. Ensuite, les 13 caractères du numéro ISBN sont lus avec read. Pour le contrôle, le script dans l'exemple sort les données lues.
Vous ne pouvez utiliser la fonction seek
qu'en relation avec read
ou bien write, et non pas en relation avec sysread ou syswrite. Utilisez dans ce cas la fonction sysseek.
Positionne le pointeur de répertoire d'un descripteur de répertoire, qui a été créé auparavant avec opendir, sur un élément quelconque dans le répertoire. La condition préalable en est que la fonction telldir soit appliquée pour rechercher les numéros de position internes des éléments du répertoire.
Attend comme paramètre:
1. le descripteur de répertoire qui a été attribué quand le répertoire a été ouvert avec opendir
.
2. le numéro de position interne d'un élément du répertoire sur lequel le pointeur de répertoire doit être placé. Ces numéros de position internes ne peuvent être recherchés qu'en appelant la fonction telldir
. Il s'agit d'adresses fournies par le système de fichiers de l'ordinateur, et non pas d'une simple série continue de numéros!
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $repertoire = "/usr/texte"; opendir(DIR, $repertoire) || die "$repertoire: $!"; my @positions; my @enregistrements; for(my $i=0;$i<10;$i++) { $enregistrements[$i] = readdir(DIR); $positions[$i] = telldir(DIR); } print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; for(my $i=0;$i<10;$i++) { print "<p>enregistrements[$i] = $enregistrements[$i]<br>\n"; print "positions[$i] = $positions[$i]</p>\n"; } seekdir(DIR, $positions[5]); my $enregistrement = readdir(DIR); print "<p>positionné sur positions[5] et élément lu: $enregistrement</p>\n"; print "</body></html>\n"; closedir(DIR); |
L'exemple ne fait rien de concret, il ne sert qu'à expliquer et comprendre le principe des numéros internes. Dans l'exemple un répertoire est ouvert avec
opendir. Les dix premiers éléments du répertoire sont ensuite lus dans une boucle for avec readdir. Ce faisant, les numéros de positions des éléments lus sont également sauvegardés à savoir dans la liste @positions
. Le script CGI sort pour le contrôle les dix éléments lus et leur numéro de position trouvé. Pour tester la fonction seekdir
le pointeur est positionné sur l'un des numéros trouvés ($positions[5]
). L'élément du répertoire qui suit est lu encore une fois et sorti pour contrôle.
Quand vous positionnez le pointeur sur un élément de répertoire avec seekdir
et que vous appliquez ensuite readdir
, ce n'est pas l'élément de répertoire sur lequel vous avez positionné le pointeur qui est lu mais le suivant!
Choisit le canal d'entrée ou de sortie par défaut pour les opérations de lecture et d'écriture qui suivent.
Attend comme paramètre:
1. le descripteur du canal d'entrée ou de sortie désiré. Il peut s'agir du descripteur d'un fichier ouvert auparavant avec open, ou de l'un des canaux standard.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/plain\n\n"; open(FICHIER, ">>/usr/webconfig/users.txt") || die "$!"; my $utilisateur = "Serge"; select(FICHIER); print "\nutilisateur=$utilisateur"; close(FICHIER); select(STDOUT); print "$utilisateur est inscrit dans le fichier"; |
Dans l'exemple un entête HTTP pour du texte pur est tout d'abord envoyé au navigateur. La fonction print
écrit dans un premier temps sur le canal de sortie standard. Après quoi un fichier est ouvert en écriture pour ajouter des données. Ici le descripteur avec le nom FICHIER
est créé. Ensuite ce descripteur est choisi comme descripteur actif avec select(FICHIER)
. L'instruction print qui suit se réfère ainsi automatiquement au descripteur choisi. Pour écrire dans le fichier:
select(FICHIER);
print "\nutilisateur=$utilisateur";
équivaut donc à:
print FICHIER "\nutilisateur=$utilisateur";
.
Après que la nouvelle ligne est écrite dans le fichier et que celui-ci est fermé - le canal de sortie standard STDOUT
est à son tour choisi comme nouveau canal actif avec select
- . L'instruction print
qui suit et qui envoie une confirmation au navigateur fonctionne uniquement parce que au préalable STDOUT
a été choisi comme canal actif. autrement le canal actif serait indéfini, étant donné que le canal FICHIER
choisi auparavant comme actif a été fermé entre-temps.
Ouvre un fichier exactement comme open. Cependant, tandis que open
rappelle la façon pratique de la déviation (avec >,>>,<, ...) sur la ligne de commande, pour sysopen
c'est directement la commande d'ouverture d'un fichier liée au système qui est utilisée. L'avantage en est que vous pouvez mentionner plus précisément comment vous désirez ouvrir le fichier. L'inconvénient en est que des problèmes se présentent avec les systèmes d'exploitation qui ne supportent pas toutes les propriétés. Il est alors possible que le script Perl ne puisse pas être exécuté dans différents environnements.
Attend comme paramètre:
1. le nom du descripteur de fichier (pouvant être choisi librement),
2. le nom de chemin du fichier à ouvrir, si c'est indispensable avec mention de chemin absolue ou mention de chemin relative,
3. le mode dans lequel le fichier doit être ouvert. Il est ici conseillé d'incorporer le module Standard fcntl
, dans lequel des constantes pour les valeurs autorisées sont définies. Les constantes suivantes sont alors permises:
O_RDONLY
signifie: ouvrir un fichier en lecture seule,
O_WRONLY
signifie: ouvrir un fichier en écriture seule,
O_RDWR
signifie: ouvrir un fichier en lecture et en écriture.
Ces constantes peuvent être liées par l'opérateur de bits OU (barre verticale simple |
) avec les constantes complémentaires suivantes:
O_APPEND
signifie: n'écrire qu'à la fin du fichier,
O_CREAT
signifie: créer un nouveau fichier dans tous les cas,
O_EXCL
signifie: ne créer le fichier que s'il n'existe pas jusqu'alors,
O_SYNC
signifie: après chaque opération d'écriture la fonction de synchronisation fsync()
est appelée,
O_TRUNC
signifie: le fichier existant est ramené a 0 octet sans être effacé.
4. (facultatif) une mention pour les droits d'accès avec lesquels le fichier doit être ouvert. La mention est ici sous Unix la désignation habituelle des droits d'accès pour le propriétaire, le groupe et les autres sous la forme octale avec un 0 qui précède (par exemple 0440
) et à ne pas noter entre guillemets.
Quand le fichier peut être ouvert, la fonction renvoie la valeur true
, sinon la valeur false
.
#!/usr/bin/perl -w use strict; use Fcntl; my $fichier = "/usr/traits_esprit/actuel.txt"; sysopen(FICHIER, $fichier, O_WRONLY | O_APPEND, 0440) || die "$fichier: $!"; print FICHIER "La curiosité vous perdra\n"; close(FICHIER); |
Dans l'exemple, un fichier texte est ouvert avec sysopen
. Il est fixé ici que le fichier est ouvert en écriture seule, et cela de telle façon que les contenus écrits soient ajoutés au fichier existant (obtenu par la liaison par l'opérateur de bits de O_APPEND
). Avec print
une phrase est ajoutée au fichier. Ensuite, le fichier est fermé. Pour le faire, vous pouvez utiliser la fonction habituelle close.
La commande use Fcntl
du début est indispensable, pour accéder aux constantes telle que O_WRONLY
et O_APPEND
.
Pour des mentions telles que O_APPEND
ou O_CREAT
il peut être judicieux de faire dépendre la commande sysopen
de l'existence du fichier, car à la différence de open
, sysopen
ne crée pas automatiquement le fichier ou bien l'écrase tout simplement. La vérification peut se faire par un opérateur de test fichier ou mieux encore par la mention du mode correspondant à l'ouverture.
Lit un nombre de caractères à mentionner dans un fichier à partir de la position actuelle du pointeur de fichier et les copie dans une scalaire. Le fichier doit, c'est judicieux dans la plupart des cas avoir été ouvert avec sysopen. Autrement, s'appliquent à sysread
les mêmes règles pour l'appel et la valeur renvoyée que pour read.
Positionne le pointeur de fichier d'un descripteur de fichier qui a été créé auparavant de préférence avec sysopen, sur un endroit quelconque du fichier. Autrement, s'appliquent à sysseek
les mêmes règles pour l'appel et la valeur renvoyée que pour seek.
Écrit dans un fichier un nombre de caractères à mentionner tirés d'une variable elle aussi à mentionner à partir de la position actuelle dans cette variable. Le fichier doit dans la plupart des cas avoir été ouvert de préférence avec sysopen.
Attend comme paramètre:
1. le descripteur de fichier .
2. une scalaire qui contient les caractères à écrire dans le fichier.
3. (facultatif) le nombre de caractères à écrire dans le fichier.
4. (facultatif) décalage (Offset) - Quand les caractères à écrire de la scalaire chaîne de caractères (2.) ne commencent pas au premier caractère mais à un caractère n vous pouvez mentionner n comme décalage (le comptage commence à 0).
Quand la scalaire contient plus de données qu'il faut en écrire, seul le nombre de caractères indiqué est cependant écrit. Quand la scalaire contient moins de données qu'il faut en écrire, seul le nombre de caractères que la scalaire contient encore à partir du décalage (offset) est écrit. Quand vous ne mentionnez pas le nombre de caractères à écrire, le contenu complet de la scalaire est écrit dans le fichier.
syswrite
retourne le nombre de caractères effectivement écrits. En cas d'erreur undef
est renvoyé.
#!/usr/bin/perl use strict; use Fcntl; my $fichier = "/usr/bin/mycodes/mysecret.sys"; my $donnees = "sdclknavaoertoerigjvimfvlkmdfghjdfbjdfihgjsobijsngohijsrotigueiufgulvbdkjbndfkhv"; my $Bloc = 8; sysopen(FICHIER, $fichier, O_WRONLY | O_EXCL) || die "$fichier: $!"; for(my $i=0;$i<10;$i++) { my $Offset = $i * $Bloc; syswrite(FICHIER,$donnees,$Bloc,$Offset); } close(FICHIER); |
L'exemple écrit dans un fichier et par blocs une chaîne de caractères qui est sauvegardée dans $donnees
. Pour ce faire, les appels de sysread
figurent dans une boucle for. La boucle a 10 passages étant donné que la longueur de $donnees
comprend 80 caractères et que pour chaque opération d'écriture, 8 caractères (définis dans la scalaire $Bloc
) doivent être écrits. Il est important ici de recalculer à chaque fois le décalage, afin que ce soit toujours les 8 caractères suivants qui sont écrits et non pas toujours les 8 premiers.
L'exemple lui-même n'est sous cette forme pas particulièrement important pour la pratique car pour des petites quantités de données, il est recommandé d'écrire en une seule fois tout le contenu de $donnees
dans le fichier. Mais le principe peut être appliqué par exemple quand la quantité de données acquise de façon dynamique à partir d'autres sources peut être très grande.
Recherche la position de l'octet actuel du pointeur de fichier d'un descripteur de fichier, qui a été créé auparavant avec open.
Attend comme paramètre:
1. le descripteur de fichier.
Renvoie la position de l'octet actuel. Quand une erreur est survenue -1
est renvoyé.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $fichier = "/usr/info/readme.txt"; my @debuts_lignes = ""; open(FICHIER, "<$fichier") || die "$fichier: $!"; $debuts_lignes[0] = tell(FICHIER); my $i = 0; while(<FICHIER>) { $i++; $debuts_lignes[$i] = tell(FICHIER); } close(FICHIER); $i = 1; print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Sortie du test</title></head><body>\n"; foreach (@debuts_lignes) { print "La ligne $i commence dans le fichier avec un décalage de $_<br>\n"; $i++; } print "</body></html>\n"; |
L'exemple ouvre un fichier texte avec open
et le lit ligne par ligne dans une boucle while. Ici, dès l'ouverture et à chaque tour de boucle, la position actuelle du pointeur de fichier est recherchée avec tell
et sauvegardée à chaque fois dans l'élément suivant de la liste @debuts_lignes
. Ensuite, du code HTML est envoyé au navigateur. Ici les positions de décalage sauvegardées de chaque début de ligne sont sorties dans une boucle foreach.
Recherche le numéro de position interne de l'élément du répertoire sur lequel est placé le pointeur de répertoire d'un descripteur de répertoire, qui a été créé auparavant avec opendir.
Attend comme paramètre:
1. le descripteur de répertoire qui a été attribué avec opendir
.
Un exemple complet avec explications des fonctions interdépendantes telldir
et seekdir
est traité pour la fonction seekdir!
Cette fonction sert à écrire enregistrement par enregistrement dans un fichier ouvert précédemment avec open, des données qui ont été formatées avec format . Des exemples sont décrits en relation avec la fonction format
.
Fonctions pour la gestion de fichiers et de répertoires | |
Fonctions pour les date et heure | |
SELFHTML/Aides à la navigation CGI/Perl Fonctions Perl |
© 2001 Stefan Münz / © 2003 Traduction Serge François, 13405@free.fr
selfhtml@fr.selfhtml.org