Chapitre VII : Les flux en Java
Interractions avec le syst` eme d’exploitation
Eric.Leclercq@u-bourgogne.fr
D´epartement IEM
http://ufrsciencestech.u-bourgogne.fr http://ludique.u-bourgogne.fr/~leclercq
6 avril 2006
Plan
1 Le mod`ele de flux Organisation de l’API
Manipulation des flux binaires Entr´ees-sorties de type terminal Les tubes
2 Flux et fichiers
Exemple de flux connect´e `a un fichier
3 Persistance d’objet et s´erialisation
4 Connecter un flux `a une ressource Web
5 Java nio
Le mod`ele de canaux Canaux et fichiers Verrouillage
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Principes et d´ efinitions
Les entr´ees / sorties sont organis´ees en Java autour du concept de flux ou flot (stream)
D´efinition :
Un flux est un canal de communication entre un lecteur et un r´edacteur.
Les flux sont classifi´es en :
flux d’entr´ee qui comportent des m´ethodes de lecture ; flux de sortie qui comportent des m´ethodes d’´ecriture.
Un flux d’entr´ee est connect´e `a une source, un flux de sortie `a une cible.
La source ou la cible d’un flux peuvent ˆetre un fichier, un tampon en m´emoire, une chaˆıne de caract`eres, une connexion r´eseau, un autre flux.
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Organisation de l’API
L’API Java propose une infrastructure de flux bas´ee sur les packages java.io et java.nio.
Les flux sont des objets
Tous les flux sont des descendants des classes (abstraites) InputStream,OutputStream, Reader et Writer.
Les flux ´el´ementaires sont des flux d’octets (flux binaires).
Les classes pour les flux non structur´es (s´equences d’octets) en ´ecriture, respectivement lecture, sont OutputStream respectivementInputStream (suffixes).
Les classes pour les flux de type s´equences de caract`eres Unicode, en ´ecriture, respectivement lecture, sont Writeret respectivementReader (suffixes).
Les classesInputStreamReader et OutputStreamWriter sont des ponts entre les flux structur´es et non structur´es.
Les classes construites ` a partir d’InputStream
ObjectInputStream FileInputStream ByteArrayInputStream FilterInputStream
PipedInputStream SequenceInputStream StringBufferInputStream
BufferedInputStream DataInputStream PushBackInputStream LineNumberInputStream Object
File InputStream
Les classes construites ` a partir d’OutputStream
ObjectInputStream FileInputStream ByteArrayInputStream FilterInputStream
PipedInputStream SequenceInputStream StringBufferInputStream
BufferedInputStream DataInputStream PushBackInputStream LineNumberInputStream Object
File InputStream
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Lecture et ´ ecriture des flux binaires
InputStream et OutputStream sont les classes de base qui d´efinissent l’interface de plus bas niveau des flux d’octets.
Les m´ethodes g´en´erales de lecture sur un flux d’octets sont : int read(): lit l’octet suivant disponible sur le flux (se bloque en l’attendant) et retourne la valeur lue dans unint (valeur entre 0 et 255), retourne -1 si la fin du flux est atteinte ;
int read(byte b[])lit au plus b.length octets depuis le flux, les placent dans le tableau b, et retourne le nombre d’octets lus ou bien -1 si la fin du flux est atteinte.
Les m´ethodes g´en´erales d’´ecriture sur un flux d’octets sont : void write(int c) ´ecrit un octet, repr´esent´e par un int void write(byte[] b)´ecrit les b.length octets de b
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Entr´ ees-sorties de type terminal
La classe java.lang.System d´efini les E/S standard : in,out, err.
Par comparasion avec C on peut ´etablir la correspondance :
1 I n p u t S t r e a m s t d i n = S y s t e m . in ; 2 O u t p u t S t r e a m s t d o u t = S y s t e m . out ; 3 O u t p u t S t r e a m s t d e r r = S y s t e m . err ;
outet err ne sont pas r´eellement des OutputStream mais desPrintStream sp´ecialis´es et tr`es utiles pour l’affichage.
Il est possible de lire un caract`ere sur l’entr´ee standard avec la m´ethoderead() et de tester la fin du flux (valeur retourn´ee -1) :
1 try{ int val = S y s t e m . in . r e a d () ; } 2 c a t c h ( I O E x c e p t i o n e ) {}
3 ...
4 b y t e b =(b y t e) val ;
Entr´ ees-sorties de type terminal
Toutes les op´eration de lecture et d’´ecriture sur les flux peuvent d´eclencher une exception IOException.
la m´ehtode available() permet de v´erifier le nombre d’octets disponibles lors de la lecture pour cr´eer ensuite la structure avec la taille adapt´ee.
1 int a t t e n t e = S y s t e m . in . a v a i l a b l e () ; 2 b y t e d a t a []=new b y t e[ a t t e n t e ];
3 S y s t e m . in . r e a d ( d a t a ) ;
la m´ethode close() lib`ere les ressources syst`eme allou´ees.
InputStream propose la m´ethodeskip() pour sauter un certain nombre de d’octets.
Les enveloppes de flux
Ce principe consiste `a ajouter des fonctionnalit´es au flux.
Le plus souvent il s’agit de transformations ou de filtrage.
Un flux filtre prendre le flux cible comme argument de son constructeur et lui d´el`egue les appels avec avoir effectu´e ses op´eration de filtrage
f2.écrire()
f1.écrire() Flux f1
Flux f2
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Pont entre les flux de caract` eres et d’octets
InputStreamReader et OutputStreamWriter sont des flux de caract`eres enveloppant un flux d’octets.
Un sch´ema d’encodage permet une conversion dans les deux sens.
Le mod`ele de d’encodage peut ˆetre donn´e en param`etre au constructeur.
1 try{
2 I n p u t S t r e a m R e a d e r c o n v e r t = new I n p u t S t r e a m R e a d e r ( S y s t e m . in ) ; 3 // on e n v e l o p p e d a n s B u f f e r e d R e a d e r p o u r b ´e n ´e f i c i e r de r e a d L i n e () 4 B u f f e r e d R e d e r in = new B u f f e r e d R e a d e r ( c o n v e r t ) ;
5 S t r i n g t e s t e = in . r e a d L i n e () ;
6 int i = N u m b e r F o r m a t . g e t I n s t a n c e () . p a r s e ( t e x t e ) . i n t V a l u e () ;
7 }
8 c a t c h( I O E x c e p t i o n e ) { . . . } 9 c a t c h( P a r s e E x c e p t i o n pe ) { . . . }
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Pont entre les flux de caract` eres et d’octets
InputStream DataInputStream
read() readFloat() readInt() readLong() ...
...
write() writeFloat() writeInt()
writeLong() DataOutputStream
OutputStream
Les tubes (pipes )
D´efinition :
PipedOutputStream et PipedInputStream permettent de connecter les ext´emit´es des flux
Les pipes permettent de faire communiquer les thread sans passer par des structures globales (static)
PipedOutputStream
PipedInputStream Thread A
Thread B write()
read()
le tube
Les tubes (pipes )
Exemple de cr´eation et connexion de tubes :
1 P i p e d I n p u t S t r e a m t u b e E n t r e e = new P i p e d I n p u t S t r e a m () ;
2 P i p e d O u t p u t S t r e a m t u b e S o r t i e = new P i p e d O u t p u t S t r e a m ( t u b e E n t r e e ) ;
L’ordre inverse de cr´eation est aussi possible ;
Il est possible de cr´eer les tubes s´epar´ement et de les connecter ensuite dynamiquement au moyen de la m´ethodeconnect(); Les fluxPipedReader et PipedWriter sont r´eserv´es aux flux de caract`eres ;
Si lebuffer interne du tube est plein le processus qui ´ecrit est bloqu´e et mis en attente jusqu’a ce que le processus qui lit est fait de la place ;
De fa¸con sym´etrique, le processus lecteur est bloqu´e si le buffer est vide.
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Les tubes (pipes ) : un exemple
Processus de lecture d’un flux (fichier) :
1 i m p o r t j a v a . io . B u f f e r e d R e a d e r ; 2 i m p o r t j a v a . io . I O E x c e p t i o n ; 3 i m p o r t j a v a . io . P r i n t W r i t e r ;
4 p u b l i c c l a s s L e c t e u r e x t e n d s T h r e a d { 5 p r i v a t e P r i n t W r i t e r out = n u l l;
6 p r i v a t e B u f f e r e d R e a d e r in = n u l l;
7 p u b l i c L e c t e u r ( P r i n t W r i t e r out , B u f f e r e d R e a d e r in ) {
8 t h i s. out = out ;
9 t h i s. in = in ;
10 }
11 p u b l i c v o i d run () {
12 if ( out != n u l l && in != n u l l) {
13 try {
14 S t r i n g i n p u t ;
15 w h i l e (( i n p u t = in . r e a d L i n e () ) != n u l l) { 16 out . p r i n t l n ( i n p u t . t o U p p e r C a s e () ) ;
17 out . f l u s h () ;
18 }
19 out . c l o s e () ;
20 } c a t c h ( I O E x c e p t i o n e ) { e . p r i n t S t a c k T r a c e () ; }
21 }
22 }
23 }
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Les tubes (pipes ) : un exemple
Processus connect´e au tube :
1 i m p o r t j a v a . io . B u f f e r e d R e a d e r ; 2 i m p o r t j a v a . io . F i l e R e a d e r ; 3 i m p o r t j a v a . io . P i p e d R e a d e r ; 4 i m p o r t j a v a . io . P i p e d W r i t e r ; 5 i m p o r t j a v a . io . P r i n t W r i t e r ; 6 p u b l i c c l a s s E x e m p l e T u b e {
7 p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) t h r o w s E x c e p t i o n { 8 F i l e R e a d e r f =new F i l e R e a d e r ( " t o t o . txt " ) ;
9 B u f f e r e d R e a d e r in =new B u f f e r e d R e a d e r ( f ) ; 10
11 P i p e d W r i t e r p i p e O u t = new P i p e d W r i t e r () ; 12 P i p e d R e a d e r p i p e I n = new P i p e d R e a d e r ( p i p e O u t ) ; 13
14 P r i n t W r i t e r out = new P r i n t W r i t e r ( p i p e O u t ) ; 15 new L e c t e u r ( out , in ) . s t a r t () ;
16
17 B u f f e r e d R e a d e r bin = new B u f f e r e d R e a d e r ( p i p e I n ) ; 18 S t r i n g i n p u t ;
19
20 w h i l e (( i n p u t = bin . r e a d L i n e () ) != n u l l) { 21 S y s t e m . out . p r i n t l n ( i n p u t ) ;}
22 in . c l o s e () ;
23 }
24 }
Connecter un flux ` a un fichier (exemple)
La lecture et l’´ecriture d’octets sur un fichier se fait `a l’aide des classes FileInputStream et FileOutputStream
1 i m p o r t j a v a . io .*;
2 c l a s s C o p i e B i n a i r e F i c h i e r {
3 p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) 4 t h r o w s I O E x c e p t i o n {
5 ...
6 int c ;
7 ...
8 if ( a r g s . l e n g t h > 0) in = new F i l e I n p u t S t r e a m ( a r g s [ 0 ] ) ; 9 if ( a r g s . l e n g t h > 1) out = new F i l e O u t p u t S t r e a m ( a r g s [ 1 ] ) ; 10 w h i l e (( c = in . r e a d () ) != -1) out . w r i t e ( c ) ;
11 in . c l o s e () ; 12 out . c l o s e () ;
13 }
Association de flux pour la gestion des fichiers
D´efinition :
DataInputStream et DataOutputStream sont des flux filtrants qui permettent de lire ou d’´ecrire des chaˆınes de catact`eres et des types de base cod´es sur plusieurs octets.
DataInputStreamet DataOutputStream impl´ementent les interfacesDataInput et DataOutput.
Elles offrent des m´ethodes plus ´evolu´ees que FileOutputStream et FileInputStream
Elles proposent des m´ethodes pour envoyer des types primitifs dans le flux :writeInt etc.
L’exemple suivant montre l’enrichissement, l’association et la connexion de flux.
Un objet de type file peut ˆetre utilis´e dans les constructeurs de flux.
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Association de flux pour la gestion des fichiers
Exemple d’association avec le flux d’entr´ee standard
1 D a t a I n p u t S t r e a m dis = new D a t a I n p u t S t r e a m ( S y s t e m . in ) ; 2 d o u b l e d = dis . r e a d D o u b l e () ;
Exemple d’association avec un fichier
1 ...
2 F i l e O u t p u t S t r e a m f = new F i l e O u t p u t S t r e a m ( " fic . dat " ) ; 3 D a t a O u t p u t S t r e a m s o r t i e = new D a t a O u t p u t S t r e a m ( f ) ;
4 ...
5 D a t a O u t p u t S t r e a m s o r t i e = new D a t a O u t p u t S t r e a m ( 6 new F i l e O u t p u t S t r e a m ( " fic . dat " ) ;
7 ...
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Obtenir des propri´ et´ es d’un fichier
java.io.File est utile pour obtenir diverses propri´et´es des fichiers :
savoir si un chemin d´esigne un fichier ordinaire ou un r´epertoire savoir si l’objetest accessible en lecture ou en ´ecriture, etc.
1 F i l e c h e m i n R e p e r t o i r e =
2 new F i l e ( " / usr / l o c a l / j a v a / d o c s " ) ; 3 F i l e c h e m i n F i c h i e r =
4 new F i l e ( c h e m i n R e p e r t o i r e , " i n d e x . h t m l " ) ;
5 ...
6 if ( c h e m i n R e p e r t o i r e . i s D i r e c t o r y () &&
7 c h e m i n F i c h i e r . c a n R e a d () ) {
8 ...
9 }
Les constructeur de fichier ne l`event pas d’exception.
Il est possible de consulter les propri´et´e syst`eme (System Properties) : System.getProperty("user.dir") ;
Op´ erations principales sur les fichiers
M´ethode Type retour Description
canRead() Boolean le fichier ou le r´epertoire est-il accessible en lecture ? canWrite() Boolean le fichier ou le r´epertoire est-il accessible en ´ecriture ?
createNewFile() Boolean Cr´ee un nouveau fichier
delete() Boolean d´etruit le fichier ou le r´epertoire
exists() Boolean est-ce que le fichier ou le r´epertoire existe ?
getAbsolutePath() String renvoie le chemin absolu du fichier ou du r´epertoire
getName() String renvoie le nom du fichie ou du r´epertoire
getParent() String renvoie le nom du r´epertoire parent du fichier ou du r´epertoire
getPath() String renvoie le chemin du fichier ou du r´epertoire
isAbsolute() Boolean le chemin du fichier ou du r´epertoire est-il absolu
isDirectory() Boolean s’agit-il d’un r´epertoire ?
isFile() Boolean s’agit-il d’un fichier ?
lastModified() long renvoie la date de la derni`ere modification du fichier ou du r´epertoire
length() long renvoie la taille du fichier
list() String [] renvoie la liste des fichiers du r´epertoire
listfiles() File [] renvoie la liste des fichiers du r´epertoire sous la forme d’un tableau d’objet de typeFile
mkdir() Boolean cr´ee un r´epertoire
mkdirs() Boolean cr´ee tous les r´epertoires du chemin
renameTo(File dest) Boolean renome le fichier ou le r´epertoire
setLastModified() Boolean d´efinit l’heure de la derni`ere modification du fichier ou du r´epertoire
setReadOnly() Boolean d´efinit le fichier en lecture seule
toURL() java.net.URL g´en`ere un objet URL pour ce fichier ou r´epoertoire
Fichiers ` a acc` es direct
Si un acc`es direct `a une position quelconque du fichier est n´ecessaire, on devra utiliser la classeRandomAccessFile Fonctionne `a la fois en ´ecriture et en lecture
Un cuseur permet de se d´eplacer dans le fichier
Il faut lui adjoindre un index pour trouver les ´el´ements Il faut ˆetre capable de d´eterminer (calculer) la position d’un
´el´ements en fonction de sa taille Utiliser le m´ethode seek(int)
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Lire et ´ ecrire sur un flux de caract` eres
Les fluxde caract`eres sont des objets de classe Readerou Writer
Les m´ethodes read et write de ces classes sont analogues `a celles op´erant sur des flux d’octets, `a la diff´erence que c’est un caract`ere 16 bits qui est lu ou ´ecrit, et non un octet La conversion entre un flux d’octets et un flux de caract`eres se fait au moyen des classes OutputStreamWriter et InputStreamReader
Le principe est l’association de flux : connecter un flux d’octets `a un flux de caract`eres
InputStreamReader isr = new InputStreamReader(System.in) ;
Pour connecter un flux de caract`eres `a un fichier, si la conversion n’est pas n´ecessaire, il est plus simple de recourir aux classeFileWriter et FileReader
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Connecter un flux ` a un tampon
Les op´erations individuelles de lecture ou d’´ecriture peut ˆetre tr`es coˆuteuse
C’est le cas des acc`es `a un fichier, ou des acc`es au r´eseau Pour ´eviter des op´erations individuelles sur un octet ou sur un caract`ere `a la fois, on utilise un tampon (anglais buffer) Pour ´ecrire sur un fichier on ´ecrira sur un flux bufferis´e Les classes qui mettent en oeuvre les buffers sont :
BufferedInputStreametBufferedOutputStream pour les flux binaires
BufferedReader etBufferedWriter pour les flux de caract`eres
Connecter un flux ` a un tampon
Un flux de caract`eres de la classeBufferedReader propose des op´erations suppl´ementaires (par exemple, lecture d’une ligne de texte).
BufferedReader in =
new BufferedReader(new FileReader("toto"));
String s = in.readline();
De fa¸con similaire pour ´ecrire dans un fichier, il est pr´ef´erable de travailler avec un tampon :
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter("toto")));
out.println("un long texte");
Lire et ´ ecrire des donn´ ees brutes sur un flux binaire
pour lire et ´ecrire, non pas des octets, mais des valeurs d’un type connu, il faut utiliser les classesDataInputStreamet
DataOutputStream
Ces classes disposent de m´ethodes sp´ecialis´ees pour les types primitifs :readInt(),readDouble(), readChar(),
readBoolean()(et les m´ethodes writeXYZ correspondantes) DataOutputStream dos = new DataOutputStream(
new FileOutputStream(’toto.dat’));
...
dos.writeBoolean(false);
dos.writeInt(400);
...
dos.close();
Mˆeme exemple pour lire un entier sur l’entr´ee standard : DataInputStream dis =
new DataInputStream(System.in);
int n = dis.readInt();
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Lire et ´ ecrire des donn´ ees par blocs
Les flux peuvent ˆetre utilis´es afin de lire ou d’´ecrire des donn´ees par bloc (tableau d’octets)
Supposons que l’on dispose d’un tableau d’octets data re¸cu par exemple d’une connexion r´eseau :
On sait que ce tableau contient un bool´een et un entier On utilise les flux des classesDataInputStreamet ByteArrayInputStream
byte[] data = ...;
DataInputStream dis = new DataInputStream(
new ByteArrayInputStream(data));
...
boolean b = dis.readBoolean();
int n = dis.readInt();
dis.close();
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Lire et ´ ecrire des donn´ ees par blocs
Le tableau doit continir des donn´ees cod´ees de fa¸con compatible avec le d´ecodage r´ealis´e
Ce sera le cas sym´etriquement si le tableau d’octets a ´et´e obtenu par les classesDataOutputStream et
ByteArrayOutputStream byte[] data;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeBoolean(true);
dos.writeInt(4);
data = baos.toByteArray();
dos.close();
Principes
Les classesObjectOutputStream et ObjectInputStream permettent de rendre persistants des objets de Java en les sauvegardant au travers d’un flux associ´e `a un fichier Le flux peut aussi ˆetre associ´e `a une connexion r´eseau Seuls les objets dont la classe impl´emente l’interface Serializable peuvent b´en´eficier de ce m´ecanisme
Si un objet comporte des membres qui sont des r´ef´erences `a d’autres objets ces objets persistent aussi.
ObjectOutputStream s =
new ObjectOutputStream(new FileOutputStream("toto.dat"));
s.writeObject("Aujourd’hui");
s.writeObject(new Date());
Principes
La lecture de ces objets, qui se fait dans le mˆeme ordre que leur
´
ecriture, doit op´erer une coercition (transtypage ou casting) du type Objectvers la classe que l’on veut restituer :
ObjectInputStream s =
new ObjectInputStream(new FileInputStream("toto"));
String chaine = (String)s.readObject();
Date date = (Date)s.readObject();
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Un exemple
Le programme exemple suivant connecte un flux d’entr´ee `a une URL (vue comme un fichier)
Il transforme ce flux d’octets en un flux de caract`eres et le place dans un tampon
Les lignes successivement lues en entr´ee sont copi´ees sur la sortie standard (jusqu’`a ce que readLine retourne null)
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Un exemple
import java.net.*;
import java.io.*;
class URLReader {
public static void main(String[] args)
throws MalformedURLException, IOException { URL url = new URL("http://kundera/index.html");
BufferedReader in = new BufferedReader(
new InputStreamReader(
url.openStream()));
String ligne;
while ((ligne = in.readLine()) != null) System.out.println(ligne);
in.close();
} }
Pour continuer...
La classe Hashtable permet de stocker des valeurs en les associant `a des identificateurs uniques calcul´es `a partir des cl´es Les cl´es et valeurs ne doivent pas poss`eder la valeur null, mais en revanche peuvent ˆetre des objets de n’importe quel type
⇒s´erialiser le hastable pour g´erer un fichier de type base de donn´ees pouvant contenir n’importe quel type d’objet Java.
Comment se pr´eserver des acc`es concurrents sur les fichiers ?
Java nio
le packagejava.nio est propos´e depuis la version 1.4 de Java ;
nio = new IO (nouvelles E/S) ;
Propose des E/S non bloquantes et s´electionnables A l’origine un thread s’occupe d’une E/S´
Avec nio un thread peut prendre en charge plusieurs canaux d’E/S et tester la disponibilit´e de donn´ees
Permet l’abandon et l’interruption des E/S ce qui permet de reveiller ou stopper un thread bloqu´e sur une E/S
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Le mod` ele d’E/S de nio
Le mod`eles d’E/S du package nio est construit autour du concept debuffer ;
Les buffer de nio sont des tableaux am´elior´es destin´es `a la communication ;
nio propose la notion de buffer directs : la m´emoire associ´ee r´eside hors de la machine virtuelle Java c`ad directement dans le syst`eme d’exploitation ;
nio propose deux caract´eristiques g´en´eriques li´ees aux fichiers : le mappage en m´emoire et le verouillage ;
Les fichier mapp´es se maniuplent comme si ils ´etaient r´esident en permanence en m´emoire ;
Le verouillage s’articule autout des verrous partag´es ou exclusifs sur des zones de fichiers.
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Le mod` ele d’E/S de nio
Le package nio propose la notion de canal (subsititu´ee `a celle de flux) ;
D´efinition :
Un canal est un terminal de comminucation semble aux flux mais plus abstrait dans le sens ou l’interface ´el´ementaire des canaux ne pr´ecise rien quant aux communications mais d´efinit les m´ethodes isOpen() et close().
Les impl´ementation des canux d´edi´ees aux fichiers, socket ou
`a des p´eriph´eriques quelconques ajoutent leurs propres m´ethodes ;
nio propose les canaux princpaux suivant :FileChannel, Pipe.SinkChannel, Pipe.SourceChanel, SocketChannel, ServerSocketChaneletc.
Canaux fichiers
Le canal FileChannel est l’´equivalent de RandomAccessFile;
Un FileChannel est construit `a partir d’un
FileInputStream, d’un FileOutputStream ou d’un RandomAccessFile;
1 F i l e C h a n n e l r e a d O n l y f s = new F i l e I n p u t S t r e a m ( " fic . txt " ) . g e t C h a n n e l () ; 2 F i l e C h a n n e l r e a d W r i t e f c = new R a n d o m A c c e s s F i l e ( " fic . txt " , " rw " ) . g e t C h a n n e l
() ;
Un canal a un statut ouvert `a sa cr´eation ;
Canaux fichiers
L’utilisation d’un FileChannel se fait `a travers un buffer de type ByteBuffer;
1 try {
2 R e a d a b l e B y t e C h a n n e l c h a n n e l = new F i l e I n p u t S t r e a m ( " i n f i l e " ) . g e t C h a n n e l () ;
3 // C r e a t e a d i r e c t B y t e B u f f e r
4 B y t e B u f f e r buf = B y t e B u f f e r . a l l o c a t e D i r e c t ( 1 0 ) ;
5 int n u m R e a d = 0;
6 w h i l e ( n u m R e a d >= 0) {
7 // r e a d () p l a c e s r e a d b y t e s at the b u f f e r ’ s p o s i t i o n so the 8 // p o s i t i o n s h o u l d a l w a y s be p r o p e r l y set b e f o r e c a l l i n g r e a d
()
9 // T h i s m e t h o d s e t s the p o s i t i o n to 0
10 buf . r e w i n d () ;
11 // R e a d b y t e s f r o m the c h a n n e l 12 n u m R e a d = c h a n n e l . r e a d ( buf ) ;
13 // The r e a d () m e t h o d a l s o m o v e s the p o s i t i o n so in o r d e r to 14 // r e a d the new bytes , the b u f f e r ’ s p o s i t i o n m u s t be set b a c k
to 0
15 buf . r e w i n d () ;
16 // R e a d b y t e s f r o m B y t e B u f f e r
17 for (int i =0; i < n u m R e a d ; i ++) {
18 b y t e b = buf . get () ;
19 }
20 }
21 } c a t c h ( E x c e p t i o n e ) {
22 }
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Verouillage
Les FileChannel supportent les verrous exclusifs ou partag´e sur des zones de fichiers
Les verrous sont g´er´es par la m´ethode lock()
1 F i l e L o c k v e r r o u F i c h i e r = c a n a l f . l o c k () ;
2 int d e b u t = 0;
3 int l o n g u e u r = c a n a l f 2 . s i z e () ;
4 F i l e L o c k v e r r o u L e c t u r e = c a n a l f 2 . l o c k ( d´ebut , l o n g u e u r ,t r u e) ;
Les verrous peuvent ˆetre patag´es ou exclusifs :
un verrou exclusif empˆeche quiconque d’obtenir un verrou sur le fichier ou sur une zone ;
un verrou partag´e permet `a d’autres d’acqu´erir des verrous partag´es mais non des verrous exclusif : lorqu’on ´ecrit, on interdit toutes les ´ecritures. Lorsqu’on lit, on interdit les
´
ecritures concurrentes, les lectures concurrentes restent possibles.
Le mod`ele de flux Flux et fichiers S´erialisation Connecter un flux `a une ressource Web Java nio
Verouillage
La m´ethodelock()permet d’obetnir un verrou exclusif ; La seconde forme (avec param`etres) permet d’indiquer une longueur et un drapeau indiquant si le verrou est partag´e ou exclusif ;
L’objet retourn´e par l´e m´ethode (fileLock) sert ensuite `a relacher le verrou au moyen de la m´ethode release().