Chapitre 14 - Les Ports
Contenu
1. Historique de la traduction
2. Généralités
3. Ouverture d'un port
3.1 La fonction open
3.2 Raffinements de la fonction open
4. Fermeture d'un port
5. Lecture du contenu d'un port
6. Ecriture dans un port
7. Mise à jour d'un port
8. Attente sur un port
9. Autres modes pour un port
9.1 Mode ligne
9.2 Ecriture et lecture seules
9.3 Accés en mode direct
9.4 Sauter des données
10. Permissions d'accès sur les fichiers
11. Ports relatifs aux répertoires
1. Historique de la traduction
29 avril 2005 17:55
|
1.0.1
|
Traduction initiale
|
Philippe Le Goff
|
lp--legoff--free--fr
|
20 mai 18:55
|
1.0.1
|
Corrections mineures
|
Philippe Le Goff
|
lp--legoff--free--fr
|
2. Généralités
Les ports permettent d'accéder à des séries externes résultant de fichiers, du réseau,
de consoles, de périphériques externes, d'évenements, de codecs, ou de bases de données.
Les données d'un port sont traitées en utilisant les fonctions standards de REBOL
propres aux séries, comme décrit dans le chapitre sur les Séries.
Les ports sont utilisés aussi bien pour des entrées que pour des sorties de données.
Les types de données manipulés par un port dépendent de la façon dont celui-ci a été ouvert.
Trois types de données sont possibles :
String
|
une série d'octets, avec conversion des sauts de lignes (par défaut)
|
Binary
|
une série d'octets, sans modification de la donnée
|
Block
|
une série de valeurs REBOL
|
Un port peut être ouvert dans l'un des deux modes suivants (buffering modes) :
Mise en buffer (buffered)
|
toutes les données sont conservées en mémoire (par défaut)
|
Direct
|
les données ne sont pas conservées en mémoire
|
De plus, un port peut être ouvert avec :
Wait
|
le port attend, écoute, pour savoir si des données arrivent (par défaut)
|
No-wait
|
aucune attente de données
|
3. Ouverture d'un port
3.1 La fonction open
La fonction open initialise l'accès à un port selon des paramètres, qui
lui ont été spécifiés. La fonction peut être invoquée avec un nom de fichier, une URL,
ou un objet. De plus, il existe plusieurs raffinements qui affecterons l'opération
d'ouverture ou l'accès au contenu du port.
La méthode la plus simple pour utiliser open est de lui fournir un nom de
fichier, ou une URL en argument.
Dans l'exemple ci-dessous, un port de type fichier est ouvert :
fp: open %file.txt
La variable fp référence le port. Si le port n'est pas ouvert,
une erreur se produira. Si besoin, l'erreur peut être capturée avec la
fonction try.
Par défaut, le port est ouvert en mode "buffered".
Cela signifie qu'un fichier est accèdé et modifié en mémoire,
et que les changements ne sont pas écrits dans le fichier
tant que le port n'est pas fermé ou mis à jour.
Pour les fichiers, la fonction open créera automatiquement le fichier
si celui-ci n'existe pas auparavant.
close open %somefile.txt
if exists? %somefile.txt [print "somefile exists"]
somefile exists
Le raffinement /new peut être utilisé pour remplacer un fichier existant.
write %somefile.txt "text in some file"
print read %somefile.txt
text in some file
close insert open/new %somefile.txt "new data"
print read %somefile.txt
new data
Une fois le port ouvert, les opérations relatives aux séries comme copy,
insert, remove, clear, first, next, et length?
peuvent être utilisées pour accèder au contenu du port et le modifier.
3.2 Raffinements de la fonction open
La fonction open accepte un certain nombre de raffinements qui
peuvent être utilisés pour modifier son comportement :
/binary
|
les données du port sont binaires
|
/string
|
les données sont de type texte, les fins de ligne
sont automatiquement converties
|
/with
|
précise une fin de ligne spéciale
|
/lines
|
manipule les données une ligne à la fois ou comme un
bloc de lignes
|
/direct
|
ne met pas en mémoire
|
/new
|
crée ou recrée la cible d'un port
|
/read
|
ouverture en mode lecture seule
|
/write
|
open for write only operation
|
/no-wait
|
pas d'attente pour les données
|
/skip
|
saute une partie des données
|
/allow
|
définit les attributs des fichiers
|
/custom
|
permet des raffinements spéciaux
|
4. Fermeture d'un port
L'accès à un port se termine quand la fonction close est invoquée.
Toutes les données en mémoire qui n'ont pas été sauvées seront écrites
dans le fichier cible.
L'exemple ci-dessous ferme le port fp utilisé précedemment.
close fp
Si vous tentez de fermer un port qui n'est pas ouvert, une erreur se produira.
Un port qui a été fermé peut être réouvert, avec la fonction open :
open fp
5. Lecture du contenu d'un port
La fonction copy (utilisée pour les séries) va servir à lire les
données d'un port, une fois celui-ci ouvert :
print copy fp
I wanted the gold, and I sought it,I scrabbled and mucked like
a slave....
Cette fonction attend normalement les données du port.
Si vous ne voulez pas attendre la fin des données, ouvrez le port avec le raffinement /no-wait.
Et pour lire une partie seulement des données, utilisez copy/part :
print copy/part fp 35
I wanted the gold, and I sought it,
Notez que le deuxième argument de copy peut être soit une longueur,
soit une position au sein de la série, le contenu du port.
Pour lire juste une partie des données du port, vous pouvez utiliser
les fonctions find et copy.
a: find fp "famine"
print copy/part a find a newline
famine or scurvy -- I fought it;
Les fonctions ordinales comme first, ou de position comme next, peuvent aussi
être utilisées sur le port :
print first fp
I
print first next next fp
w
La fonction copy retournera none lorsque toutes les données du port auront été lues.
En mode /no-wait, la fonction copy renverra une chaîne vide
si aucune donnée n'est disponible avec le port.
tp: open/direct/binary/no-wait tcp://system:8000
content: make binary! 1000
while [wait tp data: copy tp] [append content data]
close tp
6. Ecriture dans un port
La fonction insert sert pour l'écriture de données dans un port.
insert fp "I was a fool to seek it."
Si le port est en mode "buffered", la modification sera répercutée seulement lorsque
le port sera fermé ou mis à jour (avec la fonction update). Si le port est
ouvert avec /direct, alors tout changement est immédiatement pris en compte.
Tous les raffinements de la fonction insert peuvent être utilisés sur le port.
Par exemple, l'écriture de 20 caractères "espace" dans le port (avec /dup):
insert/dup fp " " 20
Vous pouvez aussi utiliser sur le port les fonctions habituelles de modifications des séries, comme
remove, clear, change, append, replace, etc.
Pour effacer un seul caractère, ou bien plusieurs :
remove fp
remove/part fp 20
Et pour effacer tous les caractères restants, écrivez :
clear fp
7. Mise à jour d'un port
La fonction update force un port à rafraîchir son état selon le
fonctionnement du périphérique externe. (ici fichier).
Par exemple, lors de l'écriture d'un fichier présent en cache, la fonction update
permet de forcer le vidage du buffer.
En lecture, la fonction update peut être utilisée pour être sûr que toutes les
données en attente ont été mises en buffer.
update fp
8. Attente sur un port
La fonction wait est essentielle aux programmes gérant
de manière asynchrone des échanges de données.
Avec wait, vous pouvez attendre des données d'un ou plusieurs ports, ou bien qu'un time-out se produise.
La fonction peut accepter en argument un port unique :
wait port
mais un bloc de plusieurs ports peut aussi être fourni :
wait [port1 port2 port3]
De plus, une valeur de time-out peut également être indiquée, sous la forme d'un nombre
de secondes ou comme une valeur de type time! :
wait [port1 port2 10]
wait [port1 port2 0:00:05]
Le premier exemple indique un time-out de 10 secondes. Le second exemple sera en
time-out dans 5 secondes.
La fonction wait renvoie le premier port qui est prêt ou none si un time-out s'est produit.
ready: wait [port1 port2 10]
if ready [data: copy ready]
L'exemple précédent lira des données du premier port prêt, si un time-out ne se
produit pas avant.
Pour obtenir un bloc comprenant tous les ports prêts, utilisez le
raffinement /all :
ready: wait/all [port1 port2 10]
if ready [
foreach port ready [
append data copy port
]
]
Cet exemple ajoutera les données de tous les ports disponibles à une seule série,
appelée ici data.
Vous pouvez aussi utiliser la fonction dispatch pour évaluer un bloc, ou une
fonction basée sur les résultats de wait vis-à-vis de plusieurs ports.
dispatch [
port1 [print "port1 awake"]
port2 [print "port2 awake"]
10 [print "time-out!"]
]
Usage de /no-wait et /direct
Pour utilisez wait avec la plupart des ports, vous aurez besoin de spécifier
les raffinements /no-wait et /direct avec open. Ceci permet d'indiquer
que les fonctions habituelles pour l'accès aux données ne doivent pas être
bloquantes et que les données ne sont pas mises en cache (buffered mode).
port1: open/no-wait/direct tcp://system:8000
9. Autres modes pour un port
9.1 Mode ligne
La fonction open permet un accès en mode ligne.
Dans ce mode, la fonction first retournera une ligne de texte, plutôt qu'un
caractère. (NdT: par exemple, avec un fichier texte séquentiel).
L'exemple ci-dessous lit un fichier une ligne à la fois :
fp: open/lines %file.txt
print first fp
I wanted the gold, and I got it --
print third fp
Yet somehow life's not what I thought it,
Le raffinement /lines est aussi utile pour les protocoles Internet qui sont
orientés "lignes".
tp: open/lines tcp://server:8000
print first tp
9.2 Ecriture et lecture seules
Vous pouvez utiliser le raffinement /read pour ouvrir un port en lecture seule :
fp: open/read %file.txt
Les modifications faites en cache ne sont pas répercutées au fichier.
Pour ouvrir un port en écriture seulement, utilisez le raffinement /write :
fp: open/write %file.txt
Les ports de type fichiers ouverts avec le raffinement /write ne liront pas
les données courantes à l'ouverture du port.
La fermeture, ou la mise à jour d'un port en écriture seule force les données
existantes dans le fichier à être remplacées (écrasées).
insert fp "This is the law of the Yukon..."
close fp
print read %file.txt
This is the law of the Yukon...
9.3 Accés en mode direct
Le raffinement /direct ouvre un port sans mise en buffer (mémoire) des données.
C'est assez pratique pour accèder à des fichiers par morceaux, notamment lorsque
le fichier est trop grand pour être stocké en mémoire.
fp: open/direct %file.txt
La lecture des données avec copy entraîne la modification de la position
de la tête de la série, pour le port :
print copy/part fp 40
I wanted the gold, and I sought it,^/ I
print copy/part fp 40
scrabbled and mucked like a slave.^/Was i
En mode direct, le port sera toujours sur la position de tête :
print head? fp
true
La fonction copy renverra none lorsque la fin des données du port est atteinte.
Voici un exemple qui utilise des ports en mode direct pour copier un fichier
quelle que soit sa taille.
from-port: open/direct %a-file.jpg
to-port: open/direct %a-file.jpg
while [data: copy/part from-port 100000 ][
append to-port data
]
close from-port
close to-port
9.4 Sauter des données
Il existe deux façons de sauter les données existantes dans le port.
Premièrement, vous pouvez ouvrir le port avec le raffinement /skip. La fonction
open passera automatiquement dans le port au point spécifié.
Par exemple :
fp: open/direct/skip %file.big 1000000
fp: open/skip http://www.example.com/bigfile.dat 100000
Deuxièmement, vous pouvez utiliser la fonction skip sur le port.
Pour les fichiers qui sont ouverts avec les raffinements /direct et /binary,
l'opération de saut est identique à l'opération seek (recherche/déplacement dans un fichier)
Les données ne sont pas lues dans le cache. Ce n'est pas possible dans le mode /string
car les sauts de lignes interférent avec la valeur de saut.
fp: open/direct/binary %file.dat
fp: skip fp 100000
10. Permissions d'accès sur les fichiers
Les fichiers créés par REBOL prennent des permissions d'accès par défaut.
Sur les systèmes d'exploitation Windows et Macintosh, les fichiers sont créés avec
des privilèges permettant leur contrôle total. Sur les systèmes Unix, les fichiers sont créés avec
des permissions selon l'umask courant.
Lorsqu'on utilise open ou write pour accèder à un fichier,
le raffinement /allow peut être utilisé pour définir les permissions d'accès.
Le raffinement /allow prend un bloc en argument. Ce bloc peut être constitué de
n'importe lequel ou de tous les mots : read, write, execute.
Restrictions liées au système d'exploitation
Le raffinement /allow permettra de définir des permissions d'accès uniquement
sur les systèmes d'exploitation qui le permettent. Si le système ne supporte pas
l'attribution de certaines permissions, elles seront ignorées.
Par exemple, les fichiers sur les systèmes Unix peuvent être défini comme exécutables
(execute), mais les systèmes Windows et Macintosh ne supportent pas cette option.
Pour un système Unix, les possibilités de permissions de fichiers sont restreintes
à celles de l'utilisateur.
Suivant le système, l'usage d'/allow conduit à effacer les permissions d'accès
pour les utilisateurs.
Pour mettre un fichier en lecture seule, utilisez open/allow,
ou write/allow avec un bloc read :
write/allow %file.txt [read]
Pour donner les droits en lecture et en exécution à un fichier :
open/allow %file.txt [read execute]
Vous pouvez définir des droits similaires, en écriture :
write/allow %file.txt [read write]
Pour supprimer tous les accès à un fichier (pour les systèmes d'exploitation
qui font la différence), mettez un bloc vide pour les permissions :
write/allow %file.txt []
Pour un accès complet :
write/allow %file [read write execute]
11. Ports relatifs aux répertoires
Les ports relatifs aux répertoires vous permettent d'accèder directement à ceux-ci.
Quand vous ouvrez un répertoire, vous obtenez l'accés au répertoire présenté
comme un bloc de noms de fichiers.
mydir: open %intro/
forall mydir [print first mydir]
CVS/
history.t
intro.t
overview.t
quick.t
close mydir
Vous pouvez avancer à une position spécifique à l'intérieur de la série du répertoire
et effacer un fichier, avec par exemple le code suivant :
dir: open %.
remove next dir
close dir
Ce code efface le second fichier dans le répertoire courant. De la même manière,
remove at dir 5
devrait effacer le cinquiéme fichier dans le répertoire, et :
clear dir
devrait effacer tous les fichiers du répertoire.
Pour effacer tous les fichiers dont le nom contient "junk", vous pouvez écrire :
dir: open %intro/
while [not tail? dir] [
either find first dir "junk" [remove dir][
dir: next dir
]
]
close dir
Les modifications apportées au répertoire sont répercutées quand le port relatif au répertoire
est fermé ou quand il est mis à jour.
Pour forcer l'application d'un changement, utilisez le code suivant :
update dir
NdT : il semblerait que update ne fonctionne pas, avec le scheme 'directory.
La méthode d'accès à un répertoire peut aussi être utilisée pour changer les noms
des fichiers. Après l'ouverture du port, la ligne :
change at dir 3 %newname.txt
permet de renommer le troisième fichier dans le répertoire. Pareillement,
le nom de n'importe lequel des fichiers dans le répertoire peut être modifié.
Voici un exemple pour renommer tous les fichiers dans un répertoire en ajoutant
le mot REBOL au nom initial :
dir: open %intro/
forall dir [insert first dir "REBOL"]
close dir
NdT : l'exemple ne fonctionne pas. Bug signalé à RT.
Updated 6-Apr-2005 - Copyright REBOL Technologies - Formatted with MakeDoc2 - Translation by Philippe Le Goff
|