0% ont trouvé ce document utile (0 vote)
23 vues6 pages

LU2IN002 Cours10 Flux

Transféré par

666-489022
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
23 vues6 pages

LU2IN002 Cours10 Flux

Transféré par

666-489022
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 6

Programme du jour

LU2IN002 - Introduction à la programmation


orientée objet

1 Flux
Lecture/écriture dans un ux : principales étapes

Responsable de l'UE et du cours du vendredi : La classe File


Christophe Marsala La classe FileInputStream
(e-mail : Christophe.Marsala@lip6.fr) La classe DataInputStream
Lecture/écriture en caractères ou en octets ?
Cours du lundi : Sabrina Tollari La classe BufferedReader
(e-mail : Sabrina.Tollari@lip6.fr) La classe Scanner
(support réalisé à partir de ceux de Christophe Marsala et de Vincent Guigue)

2 Fiabilité du code
Annotations : @Override...
Assertions

Cours 10  lundi 20 novembre 2023

Programme Entrées/sorties d'un programme

Les entrées et sorties sont gérées séparément par ux

1 Flux
Lecture/écriture dans un ux : principales étapes
Entrée :
La classe File
La classe FileInputStream
La classe DataInputStream
Lecture/écriture en caractères ou en octets ?
La classe BufferedReader
La classe Scanner Sortie :

2 Fiabilité du code

JAVA = panoplie d'outils pour communiquer dans les deux sens


avec toutes sortes de sources (chiers, BD, réseaux...)

©2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 4/34

Les flux Les flux

F En Java, le package java.io (i pour input et o pour

Dénition output) contient des classes pour la manipulation des ux

Un ux (=stream) : entrées/sorties (dynamiques) d'un programme


Deux catégories de ux :

Il s'agit d'outils essentiels dès que l'on souhaite : les ux entrants pour la lecture
 classe InputStream pour lire des octets
Saisir des informations depuis clavier
 classe Reader pour lire des caractères
Écrire sur la console les ux sortants pour l'écriture
mais aussi :  classe OutputStream pour écrire des octets
Lire/écrire des chiers
 classe Writer pour écrire des caractères

Sauver les paramètres d'un programme (=écrire un chier!)


4 Ces classes sont abstraites
Le nom des classes à utiliser est préxé par :
Communiquer avec d'autres postes de travail (en réseau)
la source pour les ux entrants
Travailler à plusieurs sur un projet (=svn gérer des chiers)
 Exemples : FileInputStream, FileReader, StringReader...
Lire/écrire dans des bases de données (BD) la destination pour les ux sortants
 Exemples : FileOutputStream, FileWriter,
StringWriter...
© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 5/34 ©2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 6/34
Principales étapes La classe File : représentation des fichiers
Etape 1 : vérier l'existence du chier, les droits...

F Quelles sont les principales étapes pour la lecture ou La classe File permet de créer un objet représentant un chier
l'écriture dans un ux ?
Nombreuses opérations très intéressantes boolean exists()
Exemple : lecture / écriture de données dans un chier (=ux) concernant la manipulation des chiers : boolean isDirectory()
1 Vérier l'existence du chier, les droits en lecture et/ou
boolean isFile()
test d'existence
boolean canWrite()
écriture...
distinction chier/répertoire boolean delete()
2 Ouvrir (si besoin créer) le chier en lecture et/ou écriture eacement File[] listFiles()
3 Lire/Écrire des données dans le chier ...
boolean mkdir()
 Si besoin, vider les buers ...
Exemple :
4 Fermer le chier 1 F i l e f = new F i l e ( " t a t o o i n e . d a t " ) ;
2 if ( f . e x i s t s () ) {
F D'autres ux se gèrent comme les chiers : clavier, réseau, 3 ...
4 }
BD...
4 new File(...) = création d'un objet de la classe File qui
représente un chier, ne crée pas un chier

4 La classe File n'est pas un ux


© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 7/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 8/34

Exemple : lecture d'octets dans un fichier Les petits pièges... La fermeture des fichiers
Etapes 2 et 4 : ouvrir, ... et fermer F Où fermer le chier ?
F Quelle classe utiliser pour lire des octets dans un chier ? A Toujours fermer un chier qui a été ouvert...
=⇒ La classe FileInputStream (car la source est un chier ⇒ 1 try {
préxe File et lire des octets ⇒ InputStream) 2 FileInputStream in = new FileInputStream ( f );
3 . . . // LECTURE
il y a des exceptions à gérer 4 in.close();
il faut penser à fermer les chiers ouverts
5 } catch ( . . . ) {
6 ...
1 F i l e f = new F i l e ( " t a t o o i n e . d a t " ) ; 7 }
2 FileInputStream in = null ;
3 try { B ... même s'il y a des erreurs pendant la lecture !
4 i n = new F i l e I n p u t S t r e a m ( f ) ; // ouverture du chier 1 FileInputStream in = null;
5 // t h r o w s : F i l e N o t F o u n d E x c e p t i o n : => t r y / c a t c h 2 try {
6
3 i n = new F i l e I n p u t S t r e a m ( f ) ;
7 // i n s t r u c t i o n s de LECTURE dans l e f i c h i e r 4 . . . // LECTURE
8
5 in.close();
9 } catch ( FileNotFoundException e ) { 6 } catch ( . . . ) {
10 ... 7 in.close();
11
8 }
12 } finally {
13 if ( i n != n u l l ) { 4 Bien mettre la déclaration en dehors du try, sinon ça ne
14 in.close(); // fermeture du chier compilera pas !
15 }
}
© ©
16
2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 9/34 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 10/34

Les petits pièges... La fermeture des fichiers Lecture d'octets dans un fichier (suite)

C Solution plus élégante : Etape 3 : lire

1 try { La classe abstraite InputStream contient une méthode abstraite


2 i n = new F i l e I n p u t S t r e a m ( f ) ; read() pour lire un octet dans un ux.
3 . . . // LECTURE
4 } catch ( . . . ) { Elle est redénit dans la classe FileInputStream :
5 ... public int read() throws IOException
6 } finally{
7 in.close(); Reads a byte of data from this input stream. This method blocks if no input is
8 } yet available.
Returns: the next byte of data, or -1 if the end of the le is reached.
D Mais la solution précédente ne marche pas encore... le close Throws: IOException - if an I/O error occurs.

est susceptible de lever une exception NullPointerException


Exemple d'instructions de LECTURE :
si le chier n'est pas ouvert !
1 int c = i n . r e a d ( ) ; // l e c t u r e d ' un o c t e t d ' i n f o r m a t i o n
1 try { 2 // s u s c e p t i b l e de l e v e r I O E x c e p t i o n => t r y / c a t c h
2 i n = new F i l e I n p u t S t r e a m ( f ) ; 3 while ( c != −1) { // t a n t que f i n de f i c h i e r non a t t e i n t e
3 . . . // LECTURE 4 System . out . p r i n t ( c ) ; // a f f i c h a g e
4 } catch ( . . . ) { 5 c = in . read ( ) ; // l e c t u r e du c a r a c t è r e s u i v a n t
5 ... 6 }
6 } finally{
7 if ( i n != n u l l ) { // v é r i f i e r que l e f i c h i e r e s t o u v e r t Ce qui peut aussi s'écrire plus simplement :
8 in.close(); 1 while ( ( c = i n . r e a d ( ) ) != −1) {
9 } 2 System . out . p r i n t ( c ) ;
10 } }
© ©
3
2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 11/34 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 12/34
Limites de FileInputStream Limites → Nouvelles classes
Des classes supplémentaires enrichissent les classes de base
Exemple : classe de lecture de haut niveau : DataInputStream
Lecture octet par octet
1 F i l e f = new F i l e ( " t a t o o i n e . d a t " ) ;
 accès "bas niveau" au chier 2 FileInputStream in = null ;
Rappels Java : représentation interne 3 DataInputStream is tr ea m = n u l l ;
try {
 entiers: binaire (fort/faible) signé en complément à 2
4
5 i n = new F i l e I n p u t S t r e a m ( f ) ; // o u v e r t u r e du f i c h i e r
• byte : 1 octet 6 // on e n c a p s u l e l e f l u x dans un o b j e t D a t a I n p u t S t r e a m
• short : 2 octets 7 i s t r e a m = new D a t a I n p u t S t r e a m ( i n ) ;
• int : 4 octets 8
9 System . out . p r i n t l n ( i s t r e a m . readInt ( ) ) ;
 réels : norme IEEE 754, signe+exposant+signicande 10 System . out . p r i n t l n ( i s t r e a m . readDouble ( ) ) ;
• oat : 4 octets 11 System . out . p r i n t l n ( i s t r e a m . readFloat ( ) ) ;
• double : 8 octets 12 System . out . p r i n t l n ( i s t r e a m . readChar ( ) ) ;
13 // mais pas de f o n c t i o n s pour l e s S t r i n g . . .
 char : 2 octets (Unicode) 14

Bilan : complexe de reconstruire des valeurs lues par octet


15 } catch (...) {
16 . . . // à compl é t e r . . .
Solution : nouvelles classes accès "haut niveau" qui 17 } finally {
18 if ( i s t r e a m != n u l l )
contiennent des méthodes utiles
19 istream . close ();
20 }
Il existe une classe équivalente pour les ux de sortie
© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 13/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 14/34

Bilan : flux pour lire depuis un fichier Écriture de bas niveau


Lecture du ux (toujours du début à la n : ux séquentiel) : F Même principe pour l'écriture d'octets...
une lecture peut lever une IOException Exemple : quelle classe pour écrire des octets dans un chier ?
lecture de bas niveau : octet par octet =⇒ La classe FileOutputStream
int c = i n . r e a d ( ) ; // l e c t u r e d ' un o c t e t
// s i c v a u t −1 : f i n de f i c h i e r a t t e i n t e Signature d'un des constructeurs

lecture de haut niveau : public FileOutputStream(File file, boolean append) throws


FileNotFoundException
 encapsulation du FileInputStream dans DataInputStream
DataInputStream is tr ea m = new DataInputStream ( i n ) ; Signature proche de celle d'ouverture en lecture...
 méthodes disponibles : ... avec une option supplémentaire append : ajouter des
istream . readInt ( ) ) ; // rend un int choses à la n du chier au lieu du début
istream . readDouble ( ) ) ; // rend un double
istream . readFloat ( ) ) ; // rend un float 1 F i l e f S o r t i e = new F i l e ( " dagobah . d a t " ) ;
istream . readChar ( ) ; // rend un char 2 F i l e O u t p u t S t r e a m out = n u l l ;
3 try {

 la fermeture du ux peut se faire depuis DataInputStream 4 out = new F i l e O u t p u t S t r e a m ( f S o r t i e , true );


5 ...
istream . close (); 6 out . w r i t e ( c ) ;
 si on ne peut pas lire ce qui est demandé : EOFException
• par exemple : un int correspond à 4 octets
4 Par défaut ou si append=false, alors remplacement du chier
• utile pour détecter la n du chier existant. Gare aux catastrophes !
© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 15/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 16/34

Écriture de haut niveau Exemple : écriture d'octets dans un fichier

F Quelle classe pour écrire des entiers, réels, caractères... ? Exemple d'utilisation (Oracle Java Tutorials) :

=⇒ La classe DataOutputStream 1 FileInputStream in = null ;


2 F i l e O u t p u t S t r e a m out = n u l l ;
1 F i l e f S o r t i e = new F i l e ( " dagobah . d a t " ) ; 3
2 F i l e O u t p u t S t r e a m out = n u l l ; 4 try {
3 DataOutputStream o s t r e a m = n u l l ; 5 i n = new F i l e I n p u t S t r e a m ( " t a t o o i n e . d a t " ) ;
try {
4
6 out = new F i l e O u t p u t S t r e a m ( " dagobah . d a t " ) ;
5 out = new F i l e O u t p u t S t r e a m ( f S o r t i e , t r u e ) ; 7
6 o s t r e a m = new DataOutputStream ( out ) ; 8 int c = in . read ( ) ;
... Que fait ce
7
9 while ( c != −1) {
8 ostream . w r i t e I n t ( 1 ) ; 10 out . write( c ) ; programme ?
9 ostream . writeDouble ( 1 . 5 ) ; 11 c = i n . read ( ) ;
10 ostream . w r i t e F l o a t ( 1 . 5 f ) ; 12 }
Recopie dans le chier
11 o s t r e a m . w r i t e C h a r ( 'A ' ) ; 13 } catch (.... ) { dagobah.dat le
12 ... 14 ...
} catch ( . . . . ) { contenu du chier
13
15 } finally {
14 ... 16 if ( i n != n u l l ) { tatooine.dat
15 } finally { 17 in . close ();
16 if ( o s t r e a m != n u l l ) { 18 }
17 ostream . c l o s e ( ) ; 19 if ( out != n u l l ) {
18 } 20 out . c l o s e ( ) ;
19 } 21 }
22 }
© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 17/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 18/34
Classes pour les flux : bilan (1) Lecture/écriture en caractères ou octets ?

Package java.io
F Comment lire/écrire des caractères ?
Classe File : créer un objet pour représenter un chier
 gérer un chier ou un répertoire (créer, lire,...)
Flux :
Diérence entre caractères...
 ux entrant : input
Fichiers de textes
• classes abstraites : InputStream (général), Reader (caractères)
• accès : FileInputStream (octet), FileReader (caractères) Entêtes des chiers ... et données stockées en
 ux sortant : output XML, HTML... octets
• classes abstraites : OutputStream (général), Writer (caract.)
Parfois pour quelques Fichiers de chires
• accès : FileOutputStream (octet), FileWriter (caractères)
chires  Volume
Accès de haut niveau à un ux
 lorsque la précision n'est  Précision
 lecture : DataInputStream pas importante
 écriture : DataOutputStream  pour les chiers CSV...

© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 19/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 20/34

Lecture de cacractères dans un fichier Stratégie lecture de fichiers en caractères

Encore une nouvelle classe : BueredReader...


... qui introduit une nouvelle méthode :

public String readLine() throws IOException Une fois la ligne lue, il peut être nécessaire de la traiter...
Reads a line of text. A line is considered to be terminated by any one of a line
Séparer les mots : classe StringTokenizer du package
feed or a carriage return.
java.util
Returns: A String containing the contents of the line, not including any

line-termination characters, or null if the end of the stream has been reached  choix des séparateurs (espace, tabulation, virgule...), accès aux
Throws: IOException - If an I/O error occurs sous-chaines
Conversion avec les méthodes des classes enveloppes
1 BufferedReader in = null ;
2 FileReader fr = null ;  Exemple : dans la classe Double
try {
3
S t r i n g buf = " 1.5 " ;
4 f r = new F i l e R e a d e r ( " t a t o o i n e . t x t " ) ; //lecture de caractères 6=octets double x = Double . v a l u e O f ( b u f ) ;
5 i n = new B u f f e r e d R e a d e r ( f r ) ;
6  Méthodes similaires avec les classes Integer, Float,...
7 S t r i n g b u f = i n . readLine ( ) ;
8 w h i l e ( b u f != n u l l ){
9 System . out . p r i n t l n ( b u f ) ;
10 b u f = i n . readLine ( ) ;
11 }
12 }...
© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 21/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 22/34

Classes pour les flux : bilan (2) Stratégie alternative

Idée : combiner la lecture de chier avec un Tokenizer...


Package java.io
=⇒ la classe Scanner du package java.util.
Classe File : créer un objet pour représenter un chier
Exemples de signatures de constructeurs :
 gérer un chier ou un répertoire (créer, lire,...)
public Scanner ( InputStream source )
Flux : public S c a n n e r ( R e a d a b l e s o u r c e ) // i n t e r f a c e
 ux entrant : input 1 Scanner s = n u l l ;
• classes abstraites : InputStream (général), Reader (caractères) 2 try {
• accès : FileInputStream (octet), FileReader (caractères) 3 s = new S c a n n e r ( new B u f f e r e d R e a d e r ( new F i l e R e a d e r ( " t e x t . t x t " ) ) ) ;
w h i l e ( s . hasNext ( ) ) {
 ux sortant : output 4
5 System . out . p r i n t l n ( s . n e x t ( ) ) ;
• classes abstraites : OutputStream (général), Writer (caract.) 6 }
• accès : FileOutputStream (octet), FileWriter (caractères) 7 } catch ( . . . ) {
8 ...
Accès de haut niveau à un ux
9 } finally {
 lecture par type : DataInputStream 10 if ( s != n u l l ) {
 écriture par type : DataOutputStream 11 s . close ();
 caractères : accès par ligne : BueredReader, BueredWriter 12 }
13 }
• combiner avec StringTokeniser

 caractères : encore plus souple : Scanner Par défaut, le séparateur est un espace mais on peut le changer...
1 s . useDelimiter (" ," );
© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 23/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 24/34
Programme Enjeux du cours

Améliorer la abilité des programmes développés

Besoin d'outils pour donner conance dans le code développé...

1 Flux
1 Objectif 1 : code compilé = code fonctionnel
 les erreurs de compilation sont les plus faciles à corriger...
2 Fiabilité du code  respectons les règles de développement
Annotations : @Override...  utilisons des outils pour provoquer des erreurs de
Assertions compilation si le code prend mauvaise tournure...
 annotations (aide au compilateur)
2 Objectif 2 : en cours d'exécution, détectons les erreurs et
informons l'utilisateur
 fonctionnement des ruptures (exceptions)
 déclenchement, traitement....
3 Vers la programmation par contrat (assertions)

© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 26/34

Fiabilité = respect des règles de Exemple sur la voiture (1)


développement

Idée Implémenter une voiture = 2 visions

Pour éviter les erreurs, respecter les règles : Vision client : accès aux contrôles comme un pilote (pédales,

Choix des noms pour comprendre qui fait quoi volant)

Classes et méthodes de taille raisonnable, limiter les accès Vision développeur : physique complexe à gérer pour obtenir
public un comportement réaliste
 les opérations complexes sont déléguées à d'autres classes
 le client voit peu de choses : facile à comprendre, évite les 1 Limiter la vision public :

failles  commandes pédales/volant ⇒ public


 taille limitée = on peut envisager de relire le code de la classe  calcul de la mise à jour de la position/direction, dérapage
si nécessaire éventuel ⇒ private
Evolutivité/architecture rééchie (pour éviter les modications 2 Limiter la taille des méthodes/classes

ultérieures...), usage de nal...  gestion de la physique = moteur physique ou géométrie dans


l'espace... ⇒ classes outils, vecteur, chier gérées à part
Plus le code est clair, plus les erreurs sont faciles à voir

© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 27/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 28/34

Exemple sur la voiture (2) Vérifications statiques

Idée
Idée
Faire en sorte de vérier un maximum de chose au niveau de la
1 Code morcelé = code plus lisible
compilation...
2 Code morcelé = code testable =⇒ plus facile à corriger
Développer plusieurs fonctions main pour tester le bon
Par défaut le compilateur vérie
fonctionnement des diérentes fonctions basiques
 syntaxe (les ;, parenthèses, accolades...)
En séparant la gestion de la physique de la voiture, il devient  type des variables et compatibilité avec les instances et
possible de tester chaque fonction du moteur physique... méthodes appelées
 niveau d'accès (aux méthodes, variables...)
plus facile de tester/corriger des méthodes basiques plutôt que
D'autres propriétés sont plus diciles à montrer et nécessitent
l'ensemble d'une méthode très complexe
plus d'informations transmises au compilateur
NB : prémices de la programmation par contrat (cf cours L3 POO avancée)
 langage d'annotations

© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 29/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 30/34
Annotations standards (1/2) Annotations standards (2/2)

Solution : utilisation d'annotations


Certaines erreurs ne posent pas de problème de compilation mais
@Override : pour indiquer une redénition de méthode
provoquent des comportements étranges lors de l'exécution... Ce
Exemple :
sont les plus chères à corriger!
1 @Override
Exemple : dans la classe Point, on veut redénir toString : 2 public S t r i n g t o S t r i g ( ) { // => e r r e u r de c o m p i l a t i o n
1 public String toStrig () { 3 return " P o i n t [ x=" + x + " , y=" + y + " ] " ;
2 r e t u r n " P o i n t [ x=" + x + " , y=" + y + " ] " ;
4 }
3 }
Provoque une erreur de compilation :
 Pas d'erreur à la compilation P o i n t . j a v a : method d o e s not o v e r r i d e o r implement a method
 Pas d'exception levée à l'exécution from a s u p e r t y p e
 MAIS problème lors de l'exécution : @Override
^
P o i n t p=new P o i n t ( ) ; 1 error
System . out . p r i n t l n ( p . t o S t r i n g ( ) ) ;
Il existe de nombreuses autres annotations :
 La méthode toString de la classe Object est utilisé !!!
@Deprecated : pour indiquer un élément déprécié, engendre
F Comment demander au compilateur de signaler ce problème ? un warning

...

© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 31/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 32/34

Vérifications dynamiques Les assertions

Idées phase de dévellopement du programme, le


Lors de la

Une fois la compilation passée, il reste de nombreuses erreurs mécanisme des assertions permet au programmeur de vérier
possibles... dynamiquement des conditions

Les tests ne sont pas nis! Syntaxe : assert expr1 [ : expr2 ]


⇒ faire des tests sur les arguments des méthodes pour vérier la  expr1 est une expression booléenne
faisabilité  expr2 de type quelconque
⇒ faire des tests sur les sorties des méthodes pour vérier la Exécution :
crédibilité des résultats obtenus  expr1 est évaluée
Exemples :  si false ⇒ une AssertionError est lancée
 expr2, convertie en chaîne, est utilisée comme message
Tester si la case demandée dans un tableau existe avant de java.lang.Object
retourner le résultat extended by java.lang.Throwable
extended by java.lang.Error
Tester si la valeur de retour de la fonction carre est bien positive extended by java.lang.AssertionError
Tester si l'argument de la division est bien diérent de 0 Alternative avec des exceptions :
... 1 if ( ! e x p r 1 ) { throw new MyException ( ) ; }

© 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 33/34 © 2021-2022 C. Marsala / V. Guigue LU2IN002 - POO en Java 34/34

Vous aimerez peut-être aussi