POO Chapt 5

Télécharger au format pptx, pdf ou txt
Télécharger au format pptx, pdf ou txt
Vous êtes sur la page 1sur 25

1

CHAPITRE 5: LES ENTRÉES


& SORTIES EN JAVA
Enseignante Chayah Rim
2

Entrées / Sorties (I/O)


• Les entrées/sorties (Input/Output ou I/O) permettent à un
programme de communiquer avec certains périphériques.  Les
entrées/sorties permettent par exemple :
• de lire et d'écrire sur la console (lecture au clavier et affichage à l'écran en
mode 'caractères')
• d'accéder aux fichiers et répertoires des disques
• de communiquer avec d'autres applications (localement ou au travers du
réseau)
• Les librairies de la plate-forme Java offrent un grand nombre de
classes dédiées aux entrées/sorties. La plupart des classes se
trouvent dans le package java.io (qui comporte plus de 50
classes !).
• Au fil des versions, d'autres packages sont venus compléter la
librairie. Il y a notamment le package java.nio, le package
java.nio.file, etc.
3

Flux (Stream)
• La notion de flux (Stream) caractérise un chemin (une voie) de
communication entre une source d'information et sa
destination.
• L'accès aux informations s'effectue de manière séquentielle.
• Les librairies Java distinguent deux genres de flux :
• Les flux binaires (Byte Stream) qui peuvent représenter des données
quelconques (nombres, données structurées, programmes, sons,
images, …)
• Les flux de caractères (Character Stream) qui représentent des textes
(chaînes de caractères) au format Unicode.
4

Utilisation des flux


• La communication avec un flux comprend trois
phases :
• L'ouverture du flux, en entrée (pour la lecture) ou en
sortie (pour l'écriture)
• La répétition de la lecture ou de l'écriture des données
(généralement des bytes ou des caractères)
• La fermeture du flux
• Quelques classes importantes pour utiliser les
flux courants :
Flux d'entrée Flux de sortie
Flux binaires DataInputStream DataOutputStrea
m
Flux de BufferedReader PrintWriter
caractères
5

Lecture et écriture des flux


• Pour lire un fichier texte il faut ouvrir un flux d'entrée
• La classe FileReader constitue une des couches de base et comporte
les méthodes élémentaires pour lire le flux depuis le système de fichiers
• Pour écrire un fichier texte il faut ouvrir un flux de sortie
• La classe FileWriter constitue une des couches de base et comporte les
méthodes élémentaires pour écrire le flux sur le système de fichiers
• La lecture et l'écriture de fichiers textes sont réalisées en
enrobant la couche de base avec des outils de plus haut
niveau (imbrication)
• Mémoire tampon (buffer) pour minimiser les accès au disque
• Conversion bytes  caractères (encodage Unicode)
• Découpage en lignes / Insertion des retours à la ligne, etc.
• Illustration (pour l'écriture)
6

Écriture d'un fichier texte


• Pour écrire séquentiellement dans un fichier de texte on
peut utiliser la classe PrintWriter de la manière suivante:
• Ouverture
String filename = "C:\\Temp\\TestOut.txt";
PrintWriter p = new PrintWriter(
new BufferedWriter(
new FileWriter(filename)));
• Écriture
p.print("Hello");
p.println(" world" + 3*2);
p.println("Fin du fichier " + filename);
• Fermeture
p.close();
7

Écriture d'un fichier texte


• En plus des méthodes print() et println() la classe
PrintWriter comporte également la méthode printf()
(formatage des chaînes de caractères) et qui permet de
formater le texte écrit dans le fichier.
printf(String format, Object... args)
• Pour la syntaxe du texte de formatage, voir description
dans l'API de la classe java.util.Formatter
• Exemples:
p.printf("%.2f", resultScore);
p.printf("Nombre %d Prix %ld Total %9ld\n", nbItems, price,
price*nbItems);
p.printf("%5d%8.3f \n", i, v);
8

Lecture d'un fichier texte


• Pour lire séquentiellement le contenu d'un fichier de texte on
peut utiliser la classe BufferedReader de la manière suivante :
• Ouverture
String filename = "C:\\Temp\\TestIn.txt";
BufferedReader r = new BufferedReader( new FileReader(filename));
• Lecture (ligne par ligne)
String s;
s = r.readLine();
while (s != null) { //--- Tant qu'il y a encore des lignes...
System.out.println(s);
s = r.readLine(); }
• Fermeture
r.close();
9

Lecture d'un fichier texte


• La classe Scanner (java.util) offre différentes méthodes pour
décomposer les données d'un flux de caractères ou d'un String.
• Ouverture
String filename = "D:\\Foo\\Config\\Init.cfg";
Scanner scf = new Scanner(new BufferedReader( new
FileReader(filename)));
• Lecture (ligne par ligne, utilisation d'un 2ème Scanner pour analyser chaque
ligne)
String line;
while (scf.hasNextLine()) {
line = scf.nextLine();
Scanner scs = new Scanner(line);
scs.useDelimiter("="); //--- Séparateur (regex pattern)
String key = scs.next();
float val = scs.nextFloat(); . . . }
• Fermeture
scf.close();
10

Entrées/Sorties standard (console)


• Les flux suivants sont prédéfinis dans la classe System. Ces flux sont
toujours ouverts et on ne les ferme pas.
• System.in Entrée standard (lecture du clavier) [ InputStream ]
• System.out Sortie standard (affichage à l'écran) [ PrintStream ]
• System.err Sortie des messages d'erreur [ PrintStream ]
(souvent identique à out par défaut)

• Écriture sur la console :


System.out.print("Résultats : "); //--- Reste sur la même
ligne
System.out.println(5*4 + ", " + 6);
System.out.println(5*4 + ", " + 4+2); //--- Attention au piège !
System.err.println("Erreur : Nom de fichier incorrect");
11

Lecture au clavier
• La lecture au clavier s'effectue en imbriquant (en enrobant) le flux
standard (System.in) dans deux constructeurs de classes qui se
chargeront de la conversion des octets en caractères Unicode et
de la mise en place d'une mémoire tampon intermédiaire.
• Lecture au clavier :
BufferedReader keyboard = new BufferedReader( new
InputStreamReader(System.in));
...
String s = keyboard.readLine();
• Remarques : La méthode readLine() attend jusqu'à ce que
l'utilisateur introduise des caractères au clavier et termine la
saisie en pressant sur la touche Return (Enter). Le caractère fin
de ligne n'est pas inclus dans le String retourné. Si l'utilisateur
presse uniquement sur Return, le String sera vide (longueur = 0).
12

Lecture au clavier
• Une autre manière de faire (souvent plus pratique) est d'utiliser la
classe Scanner (java.util) qui permet également de saisir mais, en
plus, de transformer et d'interpréter ce qui a été saisi au clavier.
• Exemple d'utilisation :
Scanner scan = new Scanner(System.in);
System.out.print("Enter an integer (or 'x' to exit) : ");
while (scan.hasNextInt()) {
int i = scan.nextInt();
System.out.println("Value = " + i);
System.out.print("Enter an integer (or 'x' to exit) : ");
}
• Remarques : La classe Scanner offre de nombreuses possibilités
pour décomposer et interpréter les informations lues. Pour plus de
détail il faut consulter la documentation (API).
13

Importation des classes I/O


• La plupart des classes d'entrées/sorties se trouvent dans la
librairie (package) java.io (ou év. dans java.nio).
• Tout programme qui utilise des entrées/sorties (sauf s'il se limite
aux flux standard) devra préalablement importer toutes les classes
externes nécessaires.
• On utilisera pour cela la pseudo-instruction :
import java.io.*;
• Cette instruction doit être placée avant la déclaration de la classe
qui utilise les entrées/sorties (juste après package …).
• Elle a pour effet de rendre visible toutes les classes contenues
dans le paquetage java.io (importation sélective également
possible).
• Pour pouvoir utiliser la classe Scanner il faut également
l'importer : import java.util.Scanner;
14

Traitement des exceptions


• La plupart des opérations d'entrées/sorties risquent de générer
des exceptions du type IOException (une sous-classe
d'Exception).
• Ces exceptions (contrôlées) sont déclarées dans la signature
des méthodes concernées et le compilateur impose donc au
programmeur de les traiter ou de déclarer leur propagation.
• Il faut éviter de mettre des instructions try / catch à chaque
ligne.
• Grâce au mécanisme de propagation des exceptions, il est
possible de concentrer le traitement à un seul endroit (ou à
quelques endroits stratégiques judicieusement choisis).
• Dans les applications, il faut trouver le bon compromis et placer
les traitements d'exception aux endroits où l'on peut prendre
les mesures adéquates et/ou informer correctement l'utilisateur.
• Pas de message du genre : "Erreur d'entrée/sortie"
• Mais plutôt un message clair : "Le fichier C:\Image\Tx1.gif n'existe pas"
15

Hiérarchie de la classe IOException


• La classe IOException comporte un grand nombre de sousclasses
correspondant à différents types d'événements qui peuvent survenir
lorsqu'on travaille avec les entrées/sorties.
16
import java.io.*;
public class Pg1 {
public static void main(String [] args) {
String l, w, filename;
Lecture dans un fichier BufferedReader f, keyboard;
try {
keyboard = new BufferedReader(new
InputStreamReader(System.in));
System.out.print("Entrer le nom du fichier : ");
filename = keyboard.readLine();
f = new BufferedReader(new FileReader(filename));
l = f.readLine();
while (l != null) {
if (l.charAt(0)=='#')
System.out.println("----------");
else
System.out.println(l);
l = f.readLine();
}
f.close();
}
catch (IOException e) {
System.err.println("Erreur: " + e);
}}}
17

Décomposition (parsing) des données lues


• Les données enregistrées dans des fichiers textes sont
généralement structurées et nécessitent une phase d'analyse
et de décomposition (parsing) avant de pouvoir les utiliser.
• La plateforme Java offre différents outils pour faciliter ce travail,
par exemple :
• Classes StringTokenizer et StreamTokenizer
• Classe Scanner
• Méthode split() de la classe String
• Classes Pattern et Matcher (package java.util.regex)
• La classe StringTokenizer est la plus ancienne et, si elle est
parfois plus performante, elle est cependant moins flexible que
Scanner ou split() qui se basent sur des Expressions régulières
(regex pattern).
18

Classe Scanner
19

Classe Scanner (suite)


20

Classe StringTokenizer
21
import java.util.StringTokenizer; import java.io.*;
public class Pg2 {

Utilisation de StringTokenizer
public static void main(String [] args) {
String l, w, filename;
StringTokenizer st;
BufferedReader f, keyboard;
try {
keyboard = new BufferedReader(new
InputStreamReader(System.in));
System.out.print("Entrer le nom du fichier : ");
filename = keyboard.readLine();
f = new BufferedReader(new FileReader(filename));
l = f.readLine();
while (l != null) {
st = new StringTokenizer(l);
while (st.hasMoreTokens()) {
System.out.print("(" + st.nextToken() + ")");
}
System.out.println();
l = f.readLine();}
f.close(); }
catch (IOException e) { System.err.println("Erreur: " + e);
}}}
22

Méthode split()
• Pour décomposer une chaîne de caractères, il existe
également la méthode split() qui se trouve dans la classe
String.
• Pour le découpage de la chaîne, cette méthode se base sur
une expression régulière dont la syntaxe est définie dans la
classe Pattern (java.util.regex).
String str = "Mots, séparés, par, des, virgules";
String[] words = str.split(", ");
for (int i=0; i<words.length; i++) {
System.out.println(words[i]);
}
23

Arguments de la ligne de commande


• En Java, un programme peut recevoir des arguments lors de son
lancement (des paramètres d'exécution sur la ligne de commande).
• Dans le programme on récupère ces paramètres dans un tableau de
chaînes de caractères (String[]) transmis à la méthode main().
public class Echo {
public static void main(String[] args) {
for (int i=0 ; i<args.length; i++) {
System.out.println(args[i]);
}
if (args.length == 0)
System.out.println("No arguments");
}
}
24

Conversions types primitifs  String


• Dans les opérations d'entrées/sorties avec des flux de
caractères (notamment en lecture), des conversions entre
types primitifs et String sont fréquemment nécessaires.
• méthodes de conversion :

Remarque : D'autres fonctions de conversion sont également disponibles


dans la classe String, notamment la méthode valueOf() qui permet de
convertir en String les valeurs de tous les types primitifs.
25

public class GetRuntimeParams {


public static void main(String[] args) {
Utilisation des fonctions de int p1 = 0;
float p2 = 0;
double p3 = 0;
boolean p4 = false;
try {
p1 = Integer.parseInt(args[0]);
conversion

p2 = Float.parseFloat(args[1]);
p3 = Double.parseDouble(args[2]);
p4 = Boolean.valueOf(args[3]).booleanValue();
}
catch (Exception e) {
System.err.println("Incorrect Runtime Parameters Types or
Values");
System.err.println("Should be : int, float, double, boolean");
return;
}
...
}
}

Vous aimerez peut-être aussi