• Aucun résultat trouvé

Chapitre VII : Les flux en Java

N/A
N/A
Protected

Academic year: 2022

Partager "Chapitre VII : Les flux en Java"

Copied!
44
0
0

Texte intégral

(1)

Chapitre VII : Les flux en Java

Interractions avec le syst` eme d’exploitation

[email protected]

epartement IEM

http://ufrsciencestech.u-bourgogne.fr http://ludique.u-bourgogne.fr/~leclercq

24 avril 2008

(2)

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 Principes

Exemples

4 Connecter un flux `a une ressource Web

5 Java nio

Le mod`ele de canaux Canaux et fichiers Verrouillage

(3)

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.

(4)

Organisation de l’API

L’API Java propose une infrastructure de flux bas´ee sur les packagesjava.io et java.nio.

Les flux sont des objets

Tous les flux sont des descendants des classes (abstraites) InputStream,OutputStream,ReaderetWriter.

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 respectivement InputStream (suffixes).

Les classes pour les flux de type s´equences de caract`eres Unicode, en ´ecriture, respectivement lecture, sontWriteret respectivement Reader(suffixes).

Les classes InputStreamReaderet OutputStreamWriter sont des ponts entre les flux structur´es et non structur´es.

(5)

Les classes construites ` a partir d’InputStream

ObjectInputStream FileInputStream ByteArrayInputStream FilterInputStream

PipedInputStream SequenceInputStream StringBufferInputStream

BufferedInputStream DataInputStream PushBackInputStream LineNumberInputStream Object

File InputStream

(6)

Les classes construites ` a partir d’OutputStream

ObjectInputStream FileInputStream ByteArrayInputStream FilterInputStream

PipedInputStream SequenceInputStream StringBufferInputStream

BufferedInputStream DataInputStream PushBackInputStream LineNumberInputStream Object

File InputStream

(7)

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 un int (valeur entre 0 et 255), retourne -1 si la fin du flux est atteinte ;

int read(byte b[])lit au plus b.lengthoctets 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 lesb.lengthoctets de b

(8)

Entr´ ees-sorties de type terminal

La classejava.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 errne sont pas r´eellement des OutputStreammais des PrintStream 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´ethode read()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 ;

(9)

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´ethode skip()pour sauter un certain nombre de d’octets.

(10)

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

(11)

Pont entre les flux de caract` eres et d’octets

InputStreamReader etOutputStreamWritersont 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 ) { . . . }

(12)

Pont entre les flux de caract` eres et d’octets

InputStream DataInputStream

read() readFloat() readInt() readLong() ...

...

write() writeFloat() writeInt()

writeLong() DataOutputStream

OutputStream

(13)

Les tubes (pipes)

D´efinition :

PipedOutputStreamet 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

(14)

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.

(15)

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 }

(16)

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 }

(17)

Connecter un flux ` a un fichier (exemple)

La lecture et l’´ecriture d’octets dans un fichier se fait `a l’aide des classesFileInputStream etFileOutputStream

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 }

(18)

Association de flux pour la gestion des fichiers

D´efinition :

DataInputStreametDataOutputStream 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.

DataInputStream etDataOutputStream impl´ementent les interfaces DataInputet 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 : writeIntetc.

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.

(19)

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 ...

(20)

Obtenir les propri´ et´ es d’un fichier

java.io.File est utile pour obtenir diverses propri´et´es de fichiers :

savoir si un chemin d´esigne un fichier ordinaire ou un r´epertoire savoir si l’objet est 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 constructeurs de fichier ne l`event pas d’exception.

(21)

Obtenir les propri´ et´ es syst` eme

Il est possible de consulter les propri´et´es syst`eme (System Properties) : System.getProperty("cl´e") ;. La cl´e peut prendre les valeurs suivantes :

file.separator line.separator user.dir

java.version java.home

java.class.path etc.

(22)

Op´ erations principales sur les fichiers

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 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 efinit l’heure de la derni`ere modification du fichier ou du r´epertoire

setReadOnly() Boolean efinit le fichier en lecture seule

toURL() java.net.URL en`ere un objet URL pour ce fichier ou r´epoertoire

(23)

Fichiers ` a acc` es direct

La classe RandomAccessFile peut ˆetre utilis´ee si un acc`es direct `a une position quelconque du fichier est n´ecessaire 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

Le constructeur RandomAccessFile(String name, String mode) s’emploie avec une chaˆıne de caract`eres contenant le nom de fichier suivi du mode d’acc`esrpour lecture ou rw pour lecture et ´ecriture.

Le constructeur RandomAccessFile(File file, String mode) fait de mˆeme `a partir d’un objet File

(24)

Fichiers ` a acc` es direct

Pour naviguer dans le fichier :

utiliser un pointeur qui indique la position dans le fichier ou les op´erations de lecture ou de mise `a jour doivent ˆetre effectu´ees ; la m´ethodegetFilePointer()permet de connaˆıtre la position du pointeur

la m´ethodeseek()permet de d´eplacer le pointeur : en param`etre un entier long qui r´epr´esentent la position, dans le fichier, pr´ecis´ee en octets (la premi`ere position commence `a ero).

1 i m p o r t j a v a . io . R a n d o m A c c e s s F i l e ; 2 p u b l i c c l a s s T e s t R a n d o m A c c e s F i l e { 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 try {

5 R a n d o m A c c e s s F i l e m o n F i c h i e r = new R a n d o m A c c e s s F i l e ( " m o n f i c h i e r . dat " , " rw " )

;

6 m o n F i c h i e r . s e e k ( 5 * 4 ) ; // x * s i z e o f int 7 S y s t e m . out . p r i n t l n ( m o n F i c h i e r . r e a d I n t () ) ; 8 m o n F i c h i e r . c l o s e () ;

9 } c a t c h ( E x c e p t i o n e ) { 10 e . p r i n t S t a c k T r a c e () ;

11 }

12 }

13 }

(25)

Lire et ´ ecrire sur un flux de caract` eres

Les flux de caract`eres sont des objets de classeReaderou Writer

Les m´ethodes read etwrite 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 OutputStreamWriteret 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 classe FileWriteret FileReader

(26)

Connecter un flux ` a un tampon

Les op´erations individuelles de lecture ou d’´ecriture peut ˆetre tr`es coˆuteuses

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 (buffer)

Pour ´ecrire sur un fichier on ´ecrira dans un flux bufferis´e Les classes qui mettent en oeuvre les buffers sont :

BufferedInputStreametBufferedOutputStreampour les flux binaires

BufferedReaderetBufferedWriterpour les flux de caract`eres

(27)

Connecter un flux ` a un tampon

Un flux de caract`eres de la classe BufferedReaderpropose 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");

(28)

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();

eme exemple pour lire un entier sur l’entr´ee standard : DataInputStream dis =

new DataInputStream(System.in);

int n = dis.readInt();

(29)

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 depuis 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();

(30)

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 si le tableau d’octets a ´et´e obtenu par les classes DataOutputStream etByteArrayOutputStream byte[] data;

ByteArrayOutputStream baos = new ByteArrayOutputStream();

DataOutputStream dos = new DataOutputStream(baos);

dos.writeBoolean(true);

dos.writeInt(4);

data = baos.toByteArray();

dos.close();

(31)

Principes

Les classes ObjectOutputStreametObjectInputStream permettent de rendre persistants des objets de Java en les sauvegardant au travers d’un flux associ´e `a un fichier Si un objet comporte des membres qui sont des r´ef´erences `a d’autres objets ces objets persistent aussi.

Afin de pouvoir s´erialiser un objet d’une classe donn´ee, celle-ci doit impl´ementer l’interface Serializable ou h´eriter d’une classe elle-mˆeme s´erialisable.

L’interface Serializablene poss`ede aucun attribut et aucune m´ethode, elle sert uniquement `a identifier une classe s´erialisable.

Tous les attributs de l’objet sont s´erialis´es mais `a certaines conditions :

ˆ

etre lui-mˆeme s´erialisable ou ˆetre un type primitif ne pas ˆetre d´eclar´estatic

ne pas ˆetre d´eclar´e `a l’aide du mot cl´e transient

(32)

Exemple de cr´ eation

UnserialVersionUID est un num´ero de version, associ´e `a toute classe impl´ementant l’interface Serializable.

il permet de s’assurer que lors de la d´es´erialisation les versions des classes Java sont concordantes.

Si le test ´echoue, une InvalidClassException est lev´ee.

Une classe s´erialisable peut d´eclarer explicitement son serialVersionUID

Si une classe s´erialisable ne d´eclare pas explicitement un serialVersionUID, Java en calcule un par d´efaut.

Il est fortement recommand´e de d´eclarer explicitement le serialVersionUID.

private static final long serialVersionUID = 123L;

ObjectOutputStream s =

new ObjectOutputStream(new FileOutputStream("toto.dat"));

s.writeObject("Aujourd’hui");

s.writeObject(new Date());

(33)

Exemple de restitution

La lecture de ces objets 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();

(34)

Un exemple

Unflux peut aussi ˆetre associ´e `a une connexion r´eseau et permettre d’envoyer des objets s´erialisables au travers tu r´eseau (chapitre 8)

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 readLineretourne null)

(35)

Un exemple

1 i m p o r t j a v a . net .*;

2 i m p o r t j a v a . io .*;

3 c l a s s U R L R e a d e r {

4 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 ) 5 t h r o w s M a l f o r m e d U R L E x c e p t i o n , I O E x c e p t i o n { 6 URL url = new URL ( " h t t p :// k u n d e r a / i n d e x . h t m l " ) ; 7 B u f f e r e d R e a d e r in =

8 new B u f f e r e d R e a d e r ( 9 new I n p u t S t r e a m R e a d e r ( 10 url . o p e n S t r e a m () ) ) ; 11 S t r i n g l i g n e ;

12 w h i l e (( l i g n e = in . r e a d L i n e () ) != n u l l) 13 S y s t e m . out . p r i n t l n ( l i g n e ) ;

14 in . c l o s e () ;

15 }

16 }

(36)

Pour continuer...

Comment se comporte le m´ecanisme de s´erialisation vis `a vis de l’h´eritage ?

Comment sp´ecialiser ou modifier la s´erialisation ?

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

erialiser le hastable pour g´erer un fichier de type base de donn´ees pouvant contenir n’importe quel type d’objet Java.

ComparaisonHashtableetHashmap, solutions ?

Comment se pr´eserver des acc`es concurrents sur les fichiers ?

(37)

Java nio

le package java.nioest 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 (comme en C) Permet l’abandon et l’interruption des E/S donc de reveiller ou stopper un thread bloqu´e sur une E/S

(38)

Le mod` ele d’E/S de nio

Le mod`eles d’E/S du package nio est construit autour du concept de buffer;

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.

(39)

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 semblable 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´ethodesisOpen()et close().

Les impl´ementation des canaux d´edi´ees aux fichiers, sockets 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.

(40)

Canaux fichiers

Le canal FileChannel est l’´equivalent de RandomAccessFile;

UnFileChannel est construit `a partir d’un

FileInputStream, d’unFileOutputStream 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 ;

(41)

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 }

(42)

Verouillage

Les FileChannel supportent les verrous exclusifs ou partag´e sur des zones de fichiers

Les verrous sont g´er´es par la m´ethodelock()

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.

(43)

Verouillage

La m´ethode lock()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 la m´ethode (fileLock) sert ensuite `a relacher le verrou au moyen de la m´ethoderelease().

Tr`es utile pour des interactions lecteurs r´edacteurs.

(44)

Verouillage

1 p u b l i c c l a s s l o c k {

2 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 arg []) {

3 try {

4 // Get a f i l e c h a n n e l for the f i l e 5 F i l e f i l e = new F i l e ( " l o c k . j a v a " ) ;

6 F i l e C h a n n e l c h a n n e l = new R a n d o m A c c e s s F i l e ( file , " rw " ) . g e t C h a n n e l () ; 7

8 // Use the f i l e c h a n n e l to c r e a t e a l o c k on the f i l e . 9 // T h i s m e t h o d b l o c k s u n t i l it can r e t r i e v e the l o c k . 10 F i l e L o c k l o c k = c h a n n e l . l o c k () ;

11

12 // Try a c q u i r i n g the l o c k w i t h o u t b l o c k i n g . T h i s m e t h o d r e t u r n s 13 // n u l l or t h r o w s an e x c e p t i o n if the f i l e is a l r e a d y l o c k e d .

14 try {

15 l o c k = c h a n n e l . t r y L o c k () ;

16 } c a t c h ( O v e r l a p p i n g F i l e L o c k E x c e p t i o n e ) {

17 // F i l e is a l r e a d y l o c k e d in t h i s t h r e a d or v i r t u a l m a c h i n e

18 }

19

20 R e a d e r r e a d e r = 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 ) ; 21 B u f f e r e d R e a d e r i n p u t = new B u f f e r e d R e a d e r ( r e a d e r ) ; 22 S y s t e m . out . p r i n t ( " A p p u y e z sur E n t r e e " ) ;

23 S t r i n g p r e n o m = i n p u t . r e a d L i n e () ; 24 // R e l e a s e the l o c k

25 l o c k . r e l e a s e () ; 26

27 // C l o s e the f i l e

28 c h a n n e l . c l o s e () ; 29 } c a t c h ( E x c e p t i o n e ) {

30 }

Références

Documents relatifs

 Les flux de trésorerie d’activité

Lorsqu’avec Marie-Hélène Ratinaud, Xavier Ronot et Geneviève Le Noan-Merdrignac nous avions coédité en 1988 un premier ouvrage en langue française, La Cytométrie en flux

Les sites qui requièrent une authentification par certificat doivent donc être placés dans une liste blanche pour laquelle le déchiffrement n’est pas effectué ; – le niveau

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

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

Eric Leclercq Chapitre VII : Les flux en Java, interractions avec le syst` eme d’exploitation... Le mod` ele

Cependant, le présent document lui-même ne peut être modifié d’aucune façon, en particulier en retirant la notice de droits de reproduction ou les références à la Internet

 Un flux est créé à partir d'un autre (par « wrapping ») : il traite les mêmes données mais avec un traitement supplémentaire..  Codage des données dans un