Entrées-sorties 2

Transcription

Entrées-sorties 2
Plan de cette partie 2
ƒ
ƒ
ƒ
Entrées-sorties 2
ƒ
ƒ
Université de Nice - Sophia Antipolis
ƒ
Version 2.1.4 – 8/7/13
Richard Grin
ƒ
ƒ
ƒ
Expressions régulières
Mise en forme des sorties
Scanner des entrées
Imprimer
Isoler les entrées-sorties
Analyse lexicale
Clavier – écran
Paquetage java.nio
Classe File
R. Grin
Java : entrées-sorties
2
Généralités
ƒ
ƒ
Expressions régulières
ƒ
R. Grin
Java : entrées-sorties
3
JDK 1.4 a ajouté des classes pour traiter les
expressions régulières « à la Perl 5.0 »
La classe String a aussi été complétée par
des nouvelles méthodes de traitement des
expressions régulières
On peut ainsi facilement rechercher des
chaînes de caractères correspondant à un
certain modèle, décomposer une chaîne en
sous-chaînes, en extraire des sous-chaînes
ou en modifier une partie
R. Grin
ƒ
La syntaxe est complexe mais on peut se
restreindre à n’utiliser que les formes les plus
simples, bien connues si on travaille avec Perl
ou Unix
Consulter la documentation de la classe
ƒ
java.util.regex.Pattern
ƒ
ƒ
ƒ
R. Grin
Java : entrées-sorties
5
4
Un caractère
Syntaxe des expressions régulières
ƒ
Java : entrées-sorties
. : n’importe quel caractère, sauf une fin de
ligne si on n’est pas en mode DOTALL (voir
méthode compile de la classe Pattern
\t, \n, \r, \f (form feed), \e (escape) ont
leur signification habituelle
\cx est le caractère Ctrl x
\uhhhh : caractère unicode dont le code
hexadécimal est hhhh
R. Grin
Java : entrées-sorties
6
1
« Échapper » un caractère
Un caractère
ƒ
[abc] : a, b ou c
ƒ
[^abc] : ni a, ni b, ni c
ƒ
[a-l] : de a à l ; [^a-l] : pas de a à l
ƒ
[a-z&&[def]] : d, e ou f (intersection)
ƒ
[a-z&&[^def]] : a à z, sauf d, e ou f
ƒ
[a-zA-Z] : union
ƒ
[a-z[A-Z]] : union
R. Grin
Java : entrées-sorties
ƒ
ƒ
7
\ : enlève la signification spéciale du caractère
suivant pour une expression régulière
Attention de ne pas oublier de doubler les « \ »
dans le code Java :
– par exemple, pour rechercher $ on doit
donner la chaîne « \\$ »
– pour rechercher « \ », on doit entrer la
chaîne « \\\\ » ; \ est un caractère spécial !
– mais pour rechercher un guillemet, il faut
entrer « \" »
R. Grin
ƒ
\d : un chiffre ; \D : pas un chiffre
\s : un espace « blanc » (espace, \t, \n, \f,
\r)
ƒ
ƒ
\S : pas un espace blanc
ƒ
ƒ
\w : une lettre ou un chiffre
ƒ
ƒ
\W : ni une lettre, ni un chiffre
ƒ
ƒ
ƒ
ƒ
R. Grin
Java : entrées-sorties
9
^ : début (et début de ligne si mode
MULTILINE, option de méthode compile
étudiée plus loin)
$ : fin (et fin de ligne si mode MULTILINE)
\b : début ou fin de mot
\B : pas un début ou fin de mot
\A : le début du texte
\z : la fin du texte
\G : la fin de la précédente chaîne
correspondant à l’expression régulière
R. Grin
Quantifieurs
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
Java : entrées-sorties
Java : entrées-sorties
10
Glouton ou pas ?
Soit X un caractère ou un groupe
X? : 0 ou 1 fois X (X est une expression
régulière quelconque)
X* : 0 ou plusieurs fois X
X+ : 1 ou plusieurs fois X
X{n} : n fois X ; X{n,} : au moins n fois X
X{n,m} : n à m fois X
R. Grin
8
« Bords »
Types de caractères prédéfinis
ƒ
Java : entrées-sorties
ƒ
ƒ
11
Par défaut, la recherche d’une chaîne de
caractères qui correspond à une expression
régulière englobe le plus de caractères possible,
tant qu’une chaîne correspond à l’expression
régulière
Si on veut que le moins de caractères possible
soient englobés, il faut ajouter ? derrière un
quantifieur
R. Grin
Java : entrées-sorties
12
2
Exemple
ƒ
ƒ
ƒ
Super-glouton
Si on cherche dans la chaîne Abcdec,
Les expressions règulières "A.*c" et "A.+c"
correspondent à Abcdec
Les expressions règulières "A.*?c" et "A.+?c"
correspondent à Abc
ƒ
ƒ
R. Grin
Java : entrées-sorties
13
ƒ
ƒ
R. Grin
Si X et Y sont des expressions régulières,
XY : X suivi de Y
X|Y : X ou Y
ƒ
(X) : X, groupe « capturé »
ƒ
\n : le nième groupe capturé
ƒ
ƒ
ƒ
R. Grin
Java : entrées-sorties
ƒ
15
Attention, si l’expression régulière est de la forme
X | Y, on ne peut travailler avec les groupes de Y
R. Grin
Java : entrées-sorties
Java : entrées-sorties
16
Autres possibilités (2)
ƒ
Si vous ne trouvez pas votre bonheur dans
la syntaxe qui vient d’être exposée, allez
voir d’autres possibilités dans la
documentation de la classe Pattern
Quelques exemples :
[a-z&&[^bc]] : de a à z, sauf b et c (&&
indique une intersection)
\p{Alpha} une lettre
\p{Blank} un espace ou une tabulation
R. Grin
14
Les groupes sont numérotés selon
l’occurrence de la parenthèse ouvrante, en
commençant par 1 pour la parenthèse la plus
à gauche
Le groupe spécial de numéro 0 correspond à
toute la chaîne qui correspond à l’expression
régulière
Autres possibilités (1)
ƒ
Java : entrées-sorties
Groupes
Opérateurs
ƒ
Un 3ème mode (+ ajouté derrière le
quantifieur) mange le plus possible de
caractères, même si ça fait ignorer une
chaîne qui pourrait correspondre à
l’expression régulière
Exemple : avec la chaîne Abdec les
expressions règulières "A.*+c" et "A.++c" ne
correspondent à rien car le caractère c final
est « mangé » par .*+ ou .++
17
D’autres exemples :
\d+(?!€) : repère des chiffres qui ne sont
pas suivis par le caractère « € » (negative
lookahead)
(?<!\d+)€ : repère le caractère « € » qui
n’est pas précédé par des chiffres (negative
lookbehind)
(?:X) : pour regrouper, par exemple pour
changer la priorité des opérateurs, sans créer
un groupe
R. Grin
Java : entrées-sorties
18
3
Méthodes de String (1)
ƒ
Exemple
boolean matches(String expreg)
String phrase =
"Bonjour bonhomme veux-tu un bon bonbon ?";
String phraseModifiee =
phrase.replaceAll("\\bbon(\\w+)", "mal$1");
System.out.println(phraseModifiee);
renvoie vrai si la chaîne (en entier) correspond
à l’expression régulière
ƒ
ƒ
String replaceAll(String expreg,
String remplacement)
renvoie une chaîne dans laquelle les souschaînes qui correspondent à expreg sont
remplacées par la chaîne remplacement ;
remplacement peut comporter des $n pour
désigner des portions parenthésées de expreg
Variante : replaceFirst
R. Grin
Java : entrées-sorties
19
ƒ
affichera
Bonjour malhomme veux-tu un bon malbon ?
ƒ
Si on veut ne pas tenir compte des majusculesminuscules, il faut utiliser les classes dédiées
Pattern et Matcher
R. Grin
Méthode split de String
ƒ
ƒ
ƒ
ƒ
éclate la chaîne en un tableau de chaînes
séparées par un délimiteur qui correspond à
l’expression régulière
2 délimiteurs accolés délimitent une chaîne
vide (pas la valeur null)
Les valeurs vides finales sont ignorées
ƒ
ƒ
ƒ
Java : entrées-sorties
21
Un 2ème paramètre n de type int peut aussi
servir à limiter à n - 1 le nombre de
recherches des délimiteurs (le dernier
élément contient la fin de la chaîne), si n > 0
Il peut faire prendre en compte les valeurs
vides finales, si n est ≠ 0
n = 0 correspond au cas où il n’y a pas de
2ème paramètre
Cette méthode rend obsolète l'utilisation de
la classe StringTokenizer
R. Grin
Java : entrées-sorties
Exemples (1)
ƒ
Décomposer en « mots » séparés par un seul
caractère blanc (4 mots « c'est », « » (chaîne
vide), « un », « test. ») :
2 espaces
Décomposer en « mots » séparés par un ou
plusieurs caractères blancs (3 mots « c'est »,
« un », « test. ») :
String[] resultat =
"c'est un test.".split("\\s+");
. . .
R. Grin
Java : entrées-sorties
22
Exemples (2)
ƒ
String[] resultat =
"c'est un test.".split("\\s");
for (int i = 0; i < resultat.length; x++)
System.out.println(resultat[i]);
ƒ
20
Compléments sur split
String[] split(String expreg)
R. Grin
Java : entrées-sorties
Décomposer en « mots » séparés par un ou
plusieurs caractères non lettre ou chiffre (4
mots « c », « est », « un », « test ») :
String[] resultat =
"c'est un test.".split("\\W+");
. . .
ƒ
Décomposer en « mots » séparés par un ou
plusieurs caractères non lettre, non chiffre, et
pas « ' » (3 mots « c’est », « un », « test ») :
String[] resultat =
"c'est
un test.".split("[^a-zA-Z0-9']+");
. . .
23
R. Grin
Java : entrées-sorties
24
4
Performances de String.split
Exemples (3)
ƒ
ƒ
Attention, avec un seul paramètre, split
ignore une ou plusieurs valeurs vides finales :
"toto,,machin,".split(",");
renvoie un tableau de 3 valeurs (une chaîne
vide entre toto et machin, mais pas à la fin)
ƒ
"toto,,machin,".split(",", -1);
ƒ
renvoie un tableau de 4 valeurs (une chaîne
vide entre toto et machin, et à la fin)
R. Grin
Java : entrées-sorties
25
Si la méthode doit être utilisée de très
nombreuses fois avec la même expression
régulière et que les performances sont
importantes, il est préférable d’utiliser la
méthode split de la classe Pattern
(l’expression régulière ne sera alors
compilée qu’une seule fois)
Même remarque pour les autres méthodes
de String qui utilisent des expressions
régulières
R. Grin
Classes dédiées
ƒ
ƒ
ƒ
Java : entrées-sorties
27
Si on veut effectuer plusieurs recherches ou
remplacement avec une même expression
régulière, il est plus performant d’utiliser
directement ces classes
Elles permettent aussi d’effectuer des
traitements complexes, autres que des simples
remplacements, à chaque occurrence d’une
chaîne correspondant à une expression régulière
R. Grin
ƒ
ƒ
Correspond à une expression régulière
« compilée », c’est-à-dire préparée pour que
les futures recherches soient accélérées
Si une expression régulière est utilisée
plusieurs fois, on a intérêt à la compiler
(donc à utiliser Pattern et pas directement
les méthodes de String)
La javadoc de cette classe décrit la syntaxe
des expressions régulières
R. Grin
Java : entrées-sorties
Java : entrées-sorties
28
Méthode compile
Classe Pattern
ƒ
26
Classes dédiées
Ces méthodes de String sont des raccourcis
qui utilisent les classes Pattern et Matcher
(du paquetage java.util.regex) dédiées aux
expressions régulières
R. Grin
Java : entrées-sorties
29
ƒ
ƒ
static Pattern compile(String exprReg)
compile une expression régulière
compile est surchargée ; un 2ème paramètre de
type int joue sur les recherches futures de
l’expression régulière (voir transparent suivant)
R. Grin
Java : entrées-sorties
30
5
Options de la méthode compile
Options de la méthode compile
Ce 2ème paramètre est un drapeau qui peut
correspondre à plusieurs options (utiliser « | »
entre 2 options pour « ajouter » les bits)
Exemple : si on veut ne pas tenir compte des
majuscules et considérer que « . » peut
correspondre à une fin de ligne, on écrit :
ƒ
ƒ
Pattern patternTR =
Pattern.compile("truc(.*?)machin",
Pattern.CASE_INSENSITIVE |
Pattern.DOTALL);
R. Grin
Java : entrées-sorties
CASE_INSENSITIVE : ne pas tenir compte des
ƒ
majuscules/minuscules (par défaut, seules les lettres du
code ASCII sont prises en compte, donc pas les lettres
accentuées)
UNICODE_CASE : toutes les lettres du code unicode sont
prises en compte pour l’option précédente
DOTALL : « . » inclut les caractères de fin de ligne (utile
quand une expression régulière peut correspondre à une
chaîne de caractères sur plusieurs lignes)
MULTILINE : ^ et $ correspondent à un début ou fin de
ligne (ou un début ou fin d’entrée)
ƒ
ƒ
ƒ
31
R. Grin
Interface CharSequence
ƒ
Java : entrées-sorties
32
Méthodes de Pattern
Les chaînes de caractères dans lesquelles on
recherche une expression régulière sont du
type CharSequence
ƒ
String[] split(CharSequence texte)
éclate le texte en prenant le pattern comme
délimiteur ; un 2ème paramètre permet de
limiter le nombre de morceaux (voir javadoc)
ƒ
static boolean matches(String
exprReg, CharSequence texte) permet
de faire directement une recherche sans
passer explicitement par la classe Matcher
(idem Pattern.compile(exprReg)
.matcher(texte).matches() )
R. Grin
Java : entrées-sorties
33
R. Grin
ƒ
Matcher matcher(CharSequence texte)
renvoie une instance de Matcher pour
rechercher l’expression régulière
dans texte (et éventuellement effectuer des
remplacements)
R. Grin
Java : entrées-sorties
34
Classe Matcher
Méthode matcher
ƒ
Java : entrées-sorties
35
ƒ
ƒ
Permet de rechercher des chaînes qui
correspondent à une expression régulière
On obtient une instance avec la méthode
matcher de la classe Pattern en donnant le
texte dans lequel se fera la recherche
Les méthodes reset(CharSequence) et
reset() réinitialisent un matcher pour
effectuer une nouvelle recherche
R. Grin
Java : entrées-sorties
36
6
Méthodes de la classe Matcher
ƒ
ƒ
ƒ
Méthodes de la classe Matcher
replaceAll , replaceFirst,
appendReplacement et appendTail
ƒ
remplacent l’expression régulière par une
chaîne de caractères
lookingAt, find et matches renvoient true
si une expression régulière a été trouvée
Si l’expression a été trouvée, on peut en savoir
plus avec les méthodes start, end et group
R. Grin
Java : entrées-sorties
37
ƒ
boolean matches() renvoie vrai si le texte en
ƒ
boolean lookingAt() renvoie vrai si le début
ƒ
entier correspond à l’expression régulière
du texte correspond à l’expression régulière
boolean find() recherche la prochaine
occurrence de l’expression régulière (utilisé le
plus souvent dans une boucle) ; renvoie false
s’il ne reste plus d’occurrence ;
find(int debut) ne recherche qu’à partir du
caractère numéro debut
Java : entrées-sorties
ƒ
ƒ
39
ƒ
ƒ
ƒ
R. Grin
Java : entrées-sorties
Java : entrées-sorties
40
Méthodes pour les groupes
Une expression régulière peut contenir des
portions entre parenthèses
Par exemple, cette expression correspond aux
sous-chaînes formées d’un mot qui commence
par « bon » ; la portion entre parenthèses
désigne le reste du mot : \bbon(\w*)
Toutes les portions entre parenthèses sont
appelées des groupes et sont numérotées par
ordre d’apparition de leur parenthèse ouvrante
dans l’expression régulière (le groupe 0 désigne
toute la sous-chaîne)
R. Grin
38
Quand une sous-chaîne qui correspond à
l’expression régulière vient d’être trouvée
(par lookingAt, find ou autre), on peut
avoir des informations sur cette sous-chaîne
String group() renvoie la sous-chaîne
int start() donne le numéro du 1er
caractère
int end() donne le numéro du dernier
caractère + 1
Groupes
ƒ
Java : entrées-sorties
Informations sur la sous-chaîne
ƒ
R. Grin
chaîne dans laquelle toutes les sous-chaînes
qui correspondent au pattern sont remplacées
par remplacement ; remplacement peut
contenir des références à des sous-groupes
du pattern ($n)
La variante replaceFirst ne remplace que
la 1ère occurrence du pattern
R. Grin
Méthodes de la classe Matcher
ƒ
String replaceAll(String
remplacement) renvoie une nouvelle
41
ƒ
ƒ
String group(int n) renvoie la souschaîne qui correspond au nième groupe de
l’occurrence qui vient d’être trouvée
(group(0) est équivalent à group())
On obtient le numéro du caractère qui débute
et termine (+ 1) chaque groupe avec les
méthodes int start(int n) et int
end(int n)
R. Grin
Java : entrées-sorties
42
7
Fin du code
Exemple de code
import java.util.regex.*;
. . .
String phrase = "Bonjour bonhomme veux-tu un
bon bonbon ?";
String expReg = "\\bbon(\\w+)";
Pattern p = Pattern.compile(
expReg, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(phrase);
System.out.println(m.replaceAll("mal$1"));
System.out.println(m.matches());
System.out.println(m.lookingAt());
System.out.println(m.find());
R. Grin
Java : entrées-sorties
// Affiche détails de la recherche
while (m.find()) {
System.out.print("Trouvé " + m.group()
+ " en position "
+ m.start());
System.out.println(" suffixe : "
+ m.group(1)
+ " en position "
+ m.start(1));
}
43
R. Grin
maljour malhomme veux-tu un bon malbon ?
false
true
true
Trouvé Bonjour en position 0 ; suffixe :
jour
Trouvé bonhomme en position 8 ; suffixe :
homme
Trouvé bonbon en position 32 ; suffixe :
bon
Java : entrées-sorties
45
ƒ
ƒ
La méthode appendReplacement offre plus de
souplesse que replaceAll : elle ajoute dans un
StringBuffer, en effectuant les
remplacements un à un
On peut choisir ce que l’on fait entre chaque
remplacement
R. Grin
Remplacement
ƒ
Matcher appendReplacement(StringBuffer
nouvTexte, String remplace) : ajoute les
StringBuffer appendTail(StringBuffer
: ajoute les caractères qui restent
après la dernière correspondance
nouvTexte)
R. Grin
Java : entrées-sorties
Java : entrées-sorties
46
Exemple de remplacement
caractères jusqu’à la fin de la précédente
correspondance (par find ou autre), son
remplacement compris
ƒ
44
Remplacement
Affichage de l’exemple
R. Grin
Java : entrées-sorties
47
// Même phrase que l’exemple précédent,
// avec la même expression régulière
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "mal$1");
System.out.println(sb);
}
// Ajoute ce qui suit la dernière occurrence
m.appendTail(sb);
System.out.println(sb);
R. Grin
Java : entrées-sorties
48
8
Affichage de l’exemple
Réinitialisation
Phrase du départ :
Bonjour bonhomme veux-tu un bon bonbon ?
Pattern : \bbon(\w+)
ƒ
maljour
maljour malhomme
maljour malhomme veux-tu un bon malbon
maljour malhomme veux-tu un bon malbon ?
R. Grin
Java : entrées-sorties
49
ƒ
ƒ
Ces 2 méthodes réinitialisent le matcher en
mettant la position courante au début (cf.
find et appendReplacement)
Matcher reset() : remet la position
courante au début du texte actuel
Matcher reset(CharSequence texte) :
change de texte et met la position courante
au début
R. Grin
Interface MatchResult
ƒ
ƒ
ƒ
ƒ
Paquetage java.util.regex
Représente une des occurrences trouvées lors
d’une recherche effectuée par un matcher ; elle
a été introduite par le JDK 5
La méthode toMatchResult() de la classe
Matcher renvoie un MatchResult que l’on
peut ensuite interroger par les méthodes end,
group, start
Cet objet renvoyé conserve les informations,
même après le déplacement du matcher à la
prochaine occurrence
R. Grin
Java : entrées-sorties
51
ƒ
ƒ
Si le fichier n’est pas trop grand, on peut lire le
fichier dans une String ou StringBuffer
dans laquelle on effectue alors les recherches
Si on peut travailler ligne par ligne, on peut
aussi lire le fichier ligne par ligne et ensuite de
rechercher dans chaque ligne
Sinon, on peut d’abord transformer le fichier
en un CharBuffer (du paquetage java.nio,
qui implémente CharSequence) pour le
passer à un pattern
R. Grin
Java : entrées-sorties
50
Exemple
List<MatchResult> resultats =
new ArrayList<MatchResult>();
Matcher m = pattern.matcher(texte);
while(m.find())
resultats.add(m.toMatchResult());
// On peut ensuite traiter les occurrences
// ou les passer à une autre méthode
. . .
R. Grin
Java : entrées-sorties
52
Exemple de recherche dans un fichier
Recherche dans un fichier
ƒ
Java : entrées-sorties
53
FileInputStream fis = . . .;
FileChannel fc = fis.getChannel();
ByteBuffer bbuf =
fc.map(FileChannel.MapMode.READ_ONLY,
0, (int)fc.size());
CharBuffer cbuf =
Charset.forName("8859_1").newDecoder().
decode(bbuf);
Pattern pattern = Pattern.compile("pat");
Matcher matcher = pattern.matcher(cbuf);
while (matcher.find())
String match = matcher.group();
R. Grin
Java : entrées-sorties
54
9
Utilisation de type envoi de mailing
ƒ
ƒ
Avec les expressions régulières on peut
créer un document qui contient des modèles
particuliers, par exemple <#nom#> qui
seront remplacés par des valeurs
correspondants au modèle (par exemple, la
valeur de la variable « nom »)
StringTemplate est un projet open source
qui a le même type de fonctionnalité
(publipostage)
R. Grin
Java : entrées-sorties
55
Java : entrées-sorties
ƒ
ƒ
ƒ
57
R. Grin
Java : entrées-sorties
56
En Java, pas de méthode printf (comme
dans le langage C) avant le JDK 5
Sans entrer dans les détails, en particulier en
ce qui concerne l’internationalisation, voici
quelques exemples qui présentent des
classes et méthodes utiles pour mettre en
forme des sorties
R. Grin
Java : entrées-sorties
58
Mise en forme des nombres
affichera (locale courante French)
1 234 567,256
1 234 567,2
1 234 567
1,234,567.2
SimpleDateFormat
Java : entrées-sorties
Projet issu du projet open source ANTLR,
qui permet de générer des textes à partir
d’un modèle qui contient des « trous » à
combler avec des données
Les trous à combler peuvent comporter des
« if », ce qui permet, par exemple, d’insérer
dans le document « Monsieur » ou
« Madame » suivant le sexe d’une personne
import java.text.NumberFormat;
import java.util.Locale;
Locale en cours
. . .
NumberFormat nf = NumberFormat.getInstance();
System.out.println(nf.format(1234567.256));
System.out.println(nf.format(1234567.2));
System.out.println(nf.format(1234567));
nf = NumberFormat.getInstance(Locale.US);
System.out.println(nf.format(1234567.2));
Pour mettre en forme les nombres et dates
La classe NumberFormat permet de mettre
en forme des nombres, des valeurs
monétaires et des pourcentages
Pour les dates, DateFormat
Ces 2 classes suffisent pour les formats les
plus courants ; sinon, on peut utiliser leur
classe fille DecimalFormat ou
R. Grin
ƒ
ƒ
Paquetage java.text
ƒ
ƒ
ƒ
Mise en forme
des sorties
R. Grin
StringTemplate
59
R. Grin
Java : entrées-sorties
60
10
Autres méthodes de NumberFormat
ƒ
Donner le nombre minimum ou maximum
de la portion du nombre située avant le
séparateur décimal :
setMinimumIntegerDigits(int n)
setMaximumIntegerDigits(int n)
ƒ
affichera (locale courante French)
Idem pour la partie décimale :
01 234 567,26
01 234 567,20
1 234 567,2
1 234 567
setMinimumFractionDigits(int n)
setMaximumFractionDigits(int n)
R. Grin
Java : entrées-sorties
Mise en forme spéciale de nombres
import java.text.*;
. . .
NumberFormat nf = new DecimalFormat("00,000,000.00");
System.out.println(nf.format(1234567.256));
System.out.println(nf.format(1234567.2));
nf = new DecimalFormat("##,000,000.##");
System.out.println(nf.format(1234567.2));
System.out.println(nf.format(1234567));
61
R. Grin
Mise en forme des dates
Les séparateurs de
milliers et décimales
sont indépendants
de la locale en cours
Java : entrées-sorties
62
Mise en forme spéciale de dates
Date maintenant = new Date();
DateFormat df = DateFormat.getDateInstance();
System.out.println(df.format(maintenant));
df = DateFormat.getDateInstance(DateFormat.MEDIUM,
Locale.US);
System.out.println(df.format(maintenant));
affichera
16 oct. 01
Oct 16, 2001
SimpleDateFormat sdf
= new SimpleDateFormat("yyyy.MM.dd G 'à' "
+ "hh:mm:ss a zzz");
Date maintenant = new Date();
System.out.println(sdf.format(maintenant));
sdf = new SimpleDateFormat("dd/MM/yyyy 'à' "
+ "HH:mm:ss");
System.out.println(sdf.format(maintenant));
Attention
aux
majuscules/
minuscules
affichera
2000.08.07 ap. J.-C. à 02:15:20 PM CEST
07/08/2000 à 14:15:20
R. Grin
Java : entrées-sorties
63
R. Grin
ƒ
NumberFormat permet aussi de mettre en
forme des valeurs monétaires et des
pourcentages avec les méthodes
getCurrencyInstance et
ƒ
Java : entrées-sorties
Les classes suivantes (du paquetage java.text)
permettent d’aller plus loin pour formater des
messages :
– ChoiceFormat pour formater différemment un
message selon la valeur d’un nombre
– MessageFormat pour définir des messages avec
du texte fixe et des parties variables
getPercentInstance
R. Grin
64
Encore plus pour formater…
Autres types de mise en forme
ƒ
Java : entrées-sorties
65
Le plus souvent ces classes sont utilisées avec
des fichiers de ressources pour internationaliser
les applications
R. Grin
Java : entrées-sorties
66
11
Exemple avec MessageFormat
Exemple avec Choice
double[] limites = {0,1,2,10};
String[] chaines =
{"Pas de fichier", "Un fichier",
"des fichiers", "beaucoup de fichiers"};
ChoiceFormat choice =
new ChoiceFormat(limites, chaines);
for (int i = -1; i < 14; i++) {
System.out.println(i + " : "
+ choice.format(i));
}
R. Grin
Java : entrées-sorties
67
R. Grin
Java : entrées-sorties
68
Méthodes format
Nouveautés du JDK 5
ƒ
double[] limites = {0,2};
String[] chaines = {"fichier", "fichiers"};
ChoiceFormat choice = new
ChoiceFormat(limites, chaines);
MessageFormat mf = new MessageFormat(
"On a trouvé {0,number,integer} {1}");
for (int i = 0; i < 5; i++) {
String choix = choice.format(i);
Object[] arguments =
new Object[] {new Integer(i), choix};
System.out.println(mf.format(arguments));
}
ƒ
Des nouvelles méthodes format ont été
ajoutées aux classes d’écriture dans un flot
et à la classe String pour faciliter la mise
en forme « à la printf de C »
ƒ
Les classes PrintStream et PrintWriter
contiennent des méthodes format qui
permettent de mettre en forme ce que l’on
envoie dans le flot de sortie
Types des paramètres :
Locale l, String format, Object... args
ƒ
Une variante prend la locale par défaut :
String format, Object... args
ƒ
R. Grin
Java : entrées-sorties
69
Les méthodes renvoient l’instance de la classe
(this ; on peut ainsi enchaîner)
R. Grin
ƒ
La classe String contient elle aussi 2
méthodes static format qui renvoient
une String (elles ont les mêmes types de
paramètres que les méthodes de
PrintStream et PrintWriter)
Elles permettent de récupérer une chaîne de
caractères mise en forme
R. Grin
Java : entrées-sorties
70
Méthodes printf
String.format
ƒ
Java : entrées-sorties
71
ƒ
Pour ne pas décontenancer les
programmeurs C, les classes PrintStream
et PrintWriter ont 2 méthodes printf
qui font exactement la même chose que les
méthodes format
R. Grin
Java : entrées-sorties
72
12
Syntaxe des formats
Exemples simples
%[n$][option][larg][.précision]type
n : numéro ordre ; 3$ se réfère au 3ème paramètre
option : par exemple, « - » pour justifier à gauche,
« , » le nombre comportera des séparateurs de milliers,
« 0 » pour imposer 0 au début (larg doit être donnée)
larg : largeur minimale de la zone réservée
précision : nombre de chiffres après la virgule
pour les nombres décimaux, largeur maximale pour les
autres types
type : le type du paramètre ; quelques types : s pour
String, d pour un entier décimal, f pour un réel
ƒ
ƒ
ƒ
ƒ
System.err.printf(
"Unable to open file '%1$s': %2$s",
fileName,
exception.getMessage());
System.err.printf(
"Unable to open file '%s': %s",
fileName,
exception.getMessage());
ƒ
ƒ
ƒ
ƒ
R. Grin
Java : entrées-sorties
73
R. Grin
ƒ
ƒ
74
Mise en forme de dates
Passage à la ligne
ƒ
Java : entrées-sorties
%n (la lettre n) fait passer à la ligne
Tient compte de la plateforme sur laquelle
on travaille
ƒ
ƒ
ƒ
On peut aussi mettre en forme des dates et des
heures ou des BigDecimal
Les dates et les heures sont adaptées à la locale
choisie (ou à la locale par défaut)
L’exemple suivant montre aussi l’utilité du
numéro d’ordre ($1)
Calendar c = ...;
String s = String.format(
"Anniversaire : %1$te %1$tB %1$tY", c);
R. Grin
Java : entrées-sorties
75
ƒ
ƒ
Seule une petite partie des possibilités a été
donnée dans ce cours
On peut trouver la syntaxe complète dans la
javadoc de la classe java.util.Formatter
ƒ
ƒ
R. Grin
Java : entrées-sorties
Java : entrées-sorties
76
Classe java.util.Formatter
Syntaxe complète des formats
ƒ
R. Grin
77
En fait les méthodes format que l’on a vues
utilisent la classe Formatter
On passe au constructeur un paramètre de type
Appendable ou String (pour un nom de
fichier) qui représente la destination de ce qui
sera mis en forme
La méthode format envoie une représentation
formatée des paramètres vers la destination
donnée dans le constructeur
R. Grin
Java : entrées-sorties
78
13
Classe java.util.Scanner
ƒ
Scanner des entrées
ƒ
R. Grin
Java : entrées-sorties
79
Depuis le JDK 5 la classe Scanner permet
de récupérer des données au milieu d’un flot
d’entrée, à l’image de la fonction scanf du
langage C
Elle implémente iterator<String>
R. Grin
ƒ
ƒ
On crée une instance de Scanner avec un de
ses nombreux constructeurs
On lui passe en paramètre le flot d’entrée dans
lequel on va extraire les données ; par
exemple, pour lire l’entrée standard :
ƒ
Scanner sc = new Scanner(System.in);
ƒ
81
(source de données de type octet) ou
InputStream, ou File, ou String
Pour InputStream et File, on peut indiquer
le nom d’un codage pour les caractères (voir
classe java.nio.Charset ; en France c’est par
défaut ISO-8859-1)
int i = sc.nextInt();
Java : entrées-sorties
Ils peuvent prendre en paramètre une
instance de java.lang.Readable (source de
données de type caractère),
java.nio.channels.ReadableByteChannel
On extrait ensuite les données une à une avec
une des méthodes nextXXX :
R. Grin
R. Grin
Délimiteurs
ƒ
Java : entrées-sorties
82
Localisation
Par défaut les données sont séparées par des
espaces, tabulations, passages à la ligne,…
(ce qui renvoie true avec la méthode
Character.isWhitespace)
ƒ
80
Constructeurs
Utilisation
ƒ
Java : entrées-sorties
ƒ
ƒ
On peut en indiquer d’autres avec la
méthode useDelimiter qui prend en
paramètre une expression régulière :
Une instance de Scanner utilise la locale
par défaut
On peut modifier la locale avec la méthode
useLocale
sc.useDelimiter("\\s*truc\\s*");
R. Grin
Java : entrées-sorties
83
R. Grin
Java : entrées-sorties
84
14
Méthodes nextXXX
Méthodes nextXXX
On trouve une méthode next par type primitif :
nextInt, nextDouble,…
et aussi nextBigDecimal, nextBigInteger
Pour les entiers, on peut passer en paramètre la
base pour les interpréter (10 par défaut)
Ces méthodes renvoient une exception
java.util.InputMismatchException (non
contrôlée) si le type de l’élément suivant ne
correspond pas au type attendu
ƒ
ƒ
ƒ
ƒ
R. Grin
Java : entrées-sorties
85
next() retourne une String qui contient la
prochaine donnée placée entre 2 délimiteurs
nextLine() avance jusqu’à la prochaine ligne
et retourne ce qui a été sauté
ƒ
ƒ
R. Grin
ƒ
ƒ
ƒ
Une méthode hasNextXXX par méthode
nextXXX : hasNextInt, hasNextDouble
(sauf pour nextLine)
Retourne true si la prochaine donnée
correspond au type que l’on cherche
Ces méthodes nextXXX et hasNextXXX
peuvent bloquer en attente du flot d’entrée
R. Grin
Java : entrées-sorties
86
Autres méthodes
Méthodes hasNextXXX
ƒ
Java : entrées-sorties
ƒ
87
findInline prend une expression régulière
en paramètre et renvoie la prochaine
occurrence dans la ligne de cette expression
régulière (ne tient pas compte des
délimiteurs)
findWithinHorizon fait de même mais
dans les n prochains caractères (n passé en
paramètre) ; 0 correspond à un horizon à
l’infini
R. Grin
Java : entrées-sorties
88
IOException
Exemple
ƒ
Scanner s = new Scanner(ligne);
s.useDelimiter("\\s*;\\s*");
nom = s.next();
age = s.nextInt();
if (s.hasNextInt()) {
option = s.nextInt();
}
ƒ
ƒ
Il n’est pas obligé de gérer les IOException
car les méthodes de Scanner ne lèvent pas
cette exception
Si une IOException survient dans le flot
sous-jacent, le scanner suppose qu’il a atteint
la fin du flot
On peut retrouver l’exception avec la
méthode ioException() de la classe
Scanner
R. Grin
Java : entrées-sorties
89
R. Grin
Java : entrées-sorties
90
15
Interfaces
ƒ
Imprimer
Le paquetage java.awt.print contient 2
interfaces pour représenter ce que l’on veut
imprimer :
– Printable correspond à un objet qui
peut s’imprimer d’une façon simple
– Pageable qui correspond à des
impressions plus complexes, avec
plusieurs formats d’impression (qui
correspondent à plusieurs Printable)
R. Grin
Java : entrées-sorties
91
R. Grin
Tâche d’impression
ƒ
On commence par obtenir une tâche
d’impression de la classe PrinterJob (du
paquetage java.awt.print) avec la méthode
ƒ
ƒ
– soit une instance de Printable (avec
setPrintable)
– soit une instance de Pageable (avec
setPageable)
Java : entrées-sorties
Il comporte une seule méthode
public int print(
Graphics graphics,
PageFormat pageFormat,
int pageIndex)
throws PrinterException
On passe ensuite à cette tâche un objet qui
représente ce que l’on veut imprimer :
R. Grin
93
Et les 2 constantes (de type int) PAGE_EXISTS
et NO_SUCH_PAGE qui peuvent être renvoyées
par la méthode print
R. Grin
Paramètres :
On remarque que, s’il y a plusieurs pages,
on doit pouvoir les écrire dans n’importe
quel ordre en donnant leur numéro, ce qui
n’est pas toujours facile
R. Grin
Java : entrées-sorties
94
class HelloImprimable implements Printable {
public int print(Graphics g,
PageFormat pf,
int pageIndex)
throws PrinterException {
if (pageIndex != 0) return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2 D)g;
g2.setFont(new Font("serif",
Font.PLAIN, 12));
g2.drawString("Hello World", 100, 100);
return PAGE_EXISTS;
}
}
– contexte graphique pour rendre la page à
imprimer (peut être casté en Graphics2D)
– format de la page d’impression qui décrit la
taille et l’orientation de la page
– numéro de la page à imprimer (0 pour la 1ère
page)
ƒ
Java : entrées-sorties
Exemple d’objet imprimable
Méthode print
ƒ
92
Interface Printable
public static PrinterJob getPrinterJob()
ƒ
Java : entrées-sorties
95
R. Grin
Java : entrées-sorties
96
16
Exemple de code pour imprimer
Zone imprimable
ƒ
PrinterJob tache = PrinterJob.getPrinterJob();
tache.setPrintable(objetAImprimer);
try {
doit implémenter
tache.print();
l’interface
}
Printable
catch(PrinterException e) { . . . }
Quand on écrit la méthode print, il faut
souvent translater le Graphics pour tenir
compte de la zone imprimable de la page :
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(),
pf.getImageableY());
R. Grin
Java : entrées-sorties
97
R. Grin
ƒ
La tâche d’impression imprime sur
l’imprimante par défaut
On peut faire afficher une fenêtre de
dialogue qui permet à l’utilisateur
d’indiquer une autre imprimante et d’autres
informations comme les pages à imprimer
renvoie
et le nombre de copies :
if (tache.printDialog())
tache.print();
R. Grin
98
Choix du format de page
Choix de l’imprimante
ƒ
Java : entrées-sorties
false si
l’utilisateur
a annulé
Java : entrées-sorties
ƒ
La tâche d’impression peut donner le format de page
par défaut :
PageFormat pf = tache.defaultPage();
ƒ
On peut modifier le format de page par défaut
– par programmation :
pf.setOrientation(PageFormat.LANDSCAPE);
– en affichant une fenêtre de dialogue :
pf = tache.pageDialog(pf);
ƒ
Pour utiliser un format de page, il suffit de le passer à
la méthode setPrintable :
tache.setPrintable(ObjetAImprimer, pf);
99
R. Grin
Exemple de code
Java : entrées-sorties
100
Interface Pageable
PrinterJob tache =
PrinterJob.getPrinterJob();
tache.setPrintable(objetAImprimer);
PageFormat pf =
tache.pageDialog(printJob.defaultPage());
if (tache.printDialog()) {
Seulement si on
try {
veut changer les
tache.print();
dimensions
de la page
}
ƒ
Elle possède 3 méthodes :
– int getNumberOfPages()
– Printable getPrintable(int numeroPage)
– PageFormat getPageFormat(int numeroPage)
catch(PrinterException e) { . . . }
}
R. Grin
Java : entrées-sorties
101
R. Grin
Java : entrées-sorties
102
17
Exemple schématique avec Book
Classe Book
ƒ
ƒ
Elle implémente l’interface Pageable
Outre les méthodes de Pageable, elle contient 3
méthodes pour ajouter ou remplacer des pages :
– void append(Printable p, PageFormat pf) :
ajoute une page (à la fin)
– void append(Printable p , PageFormat pf,
int n) : ajoute n pages (à la fin)
– void setPage(int n, Printable p,
PageFormat pf) : remplace la page numéro n
R. Grin
Java : entrées-sorties
103
Book livre = new Book();
// Ajoute 1 page en paysage et 10 en portrait
PageFormat paysage = tache.defaultPage();
paysage.setOrientation(PageFormat.LANDSCAPE);
livre.append(new Page1(), paysage);
PageFormat portrait = tache.defaultPage();
paysage.setOrientation(PageFormat.PORTRAIT);
livre.append(new Page2(), portrait, 10);
//
tache.setPageable(livre);
R. Grin
Conclusion
ƒ
ƒ
ƒ
ƒ
ƒ
Java : entrées-sorties
105
Java : entrées-sorties
Java : entrées-sorties
106
APIs open source et gratuites
JasperReports permet de générer des
rapports sophistiqués de formats divers
(PDF, HTML, XML, RTF,…) en prenant
les données dans divers sources (base de
données relationnelle, XML,…) ; iReport
est un outil wysiwyg pour générer des
fichiers de description de rapports utilisés
ensuite par JasperReports
R. Grin
Des APIs non standard sont disponibles sur
le Web pour faciliter l’impression de
rapports complexes, directement ou en
passant par l’exportation en formats divers
(le plus souvent en PDF)
Ces APIs sont fournies par des projets open
source ou par des produits commerciaux
Quelques exemples sont donnés dans les
transparents suivants
R. Grin
APIs open source et gratuites
ƒ
104
APIs non standard
L’API standard n’offre que des
fonctionnalités de bas niveau
Le programmeur doit donc ajouter
beaucoup de code s’il veut imprimer un
document de plusieurs pages, avec des
formats de pages non simplistes
R. Grin
Java : entrées-sorties
ƒ
ƒ
107
iText est une API qui permet de générer des
documents PDF ou RTF (Word)
Apache POI permet de manipuler en lecture
et écriture les fichiers associés à la suite
Office de Microsoft (fichiers Word ou
Excel en particulier)
R. Grin
Java : entrées-sorties
108
18
Autres APIs
Il est aussi possible d’utiliser XSL-FO (du
monde XML)
Crystal Reports est un produit commercial
payant (et cher !)
JPedal est un produit commercial qui offre une
version gratuite pour les organisations à but non
lucratif
Différentes librairies open source à l’adresse
ƒ
ƒ
ƒ
ƒ
Isoler les entrées-sorties
http://java-source.net/open-source/pdf-libraries
R. Grin
Java : entrées-sorties
109
R. Grin
ƒ
ƒ
ƒ
Les entrées-sorties ont souvent des API
complexes
Elles compliquent les tests
De plus, il n’est pas rare de changer de façon
d’accéder à des ressources ou données
externes (fichiers, BD relationnelle, BD
objet, XML,…)
Il vaut donc mieux isoler les entrées-sorties
du reste de l’application
R. Grin
Java : entrées-sorties
110
Implémentation
Pourquoi ?
ƒ
Java : entrées-sorties
111
Il est bon d’encapsuler les accès aux données
dans des classes à part de telle sorte que
– le reste de l’application puisse accéder aux
ressources plus facilement : interfaces
simples et adaptées à l’application
– les interfaces ne dépendent pas du type de
persistance choisi
– on puisse simuler des entrées-sorties
pendant les tests (sans nécessairement
disposer du support de persistance)
ƒ
R. Grin
Java : entrées-sorties
112
Introduction
ƒ
Analyse lexicale
ƒ
R. Grin
Java : entrées-sorties
113
Cette section étudie des classes pour
décomposer du texte en lexèmes :
– classe StringTokenizer
– classe StreamTokenizer
Autres possibilités pour effectuer la même
tâche (étudiées plus loin dans cette partie du
cours) :
– méthode split de la classe String
– classe Scanner, introduite par le JDK 5
R. Grin
Java : entrées-sorties
114
19
Avertissement
Séparateurs des données
ƒ
ƒ
Rappel : les flots de caractères utilisent des
séparateurs entre les données
Les classes étudiées dans cette section
facilitent l’extraction de données séparées par
des séparateurs
ƒ
Scanner
ƒ
R. Grin
Java : entrées-sorties
115
Analyse lexicale d’une chaîne
Java : entrées-sorties
Cependant la connaissance de cette classe
peut être utile pour comprendre du code déjà
écrit
R. Grin
Java : entrées-sorties
116
Analyse lexicale d’une chaîne
import java.util.StringTokenizer;
Pas java.io
public class Decomposition {
public static void main(String[] args) {
String donnees =
Que sera-t-il
"Chiffres : 12,,689\n155";
affiché ?
StringTokenizer st =
new StringTokenizer(donnees, " ,\n");
while (st.hasMoreTokens()) {
String token = st.nextToken(); Chiffres
:
System.out.println(token);
12
}
689
2 séparateurs accolés sont considérés
}
155
comme
1
seul
séparateur
}
R. Grin
La classe StringTokenizer ne supporte
pas l’utilisation d’expressions régulières et
elle peut donc souvent être avantageusement
remplacée par l’utilisation de méthode
split de la classe String ou par la classe
117
Que sera-t-il
. . .
affiché ?
String donnees =
Chiffres
"Chiffres : 12,,689\n155";
:
StringTokenizer st =
new StringTokenizer(donnees, " ,\n",
12
Les séparateurs sont
true);
,
des lexèmes (tokens)
while (st.hasMoreTokens()) {
,
689
String token = st.nextToken();
System.out.println(token);
}
155
R. Grin
Java : entrées-sorties
118
Analyse lexicale d’un flot
ƒ
La classe java.io.StreamTokenizer
possède un constructeur
Entrées et sorties sur
clavier - écran
public StreamTokenizer(Reader r)
ƒ
qui permet de faire une analyse syntaxique
du flot de caractères associé à r
Cette classe offre plus de souplesse que
StringTokenizer (surtout pour analyser des
programmes Java ou C) mais est plus
complexe ; elle ne sera pas étudiée dans ce
cours
R. Grin
Java : entrées-sorties
119
R. Grin
Java : entrées-sorties
120
20
Lecture caractère par caractère
Entrées-sorties sur clavier-écran
int n; char car; String s = "";
try {
while (true) {
int n = System.in.read();
if (n == -1) break;
car = (char)n;
s += car;
Cast pour avoir
}
un char
}
catch(IOException e) {
System.err.println("Erreur I/O" + e);
}
R. Grin
Java : entrées-sorties
BufferedReader br =
new BufferedReader(
new InputStreamReader(System.in));
System.out.print("Entrez votre nom : ");
String nom = br.readLine();
System.out.print("Entrez votre âge : ");
String age = br.readLine();
System.out.println(nom + " a "
+ Integer.parseInt(age) + " ans.");
121
R. Grin
ƒ
Que signifie « System.out.println() » ?
System est une classe du paquetage java.lang
Elle est final et non instanciable. Elle
comprend (entre autres) :
– 3 variables de classe : in, out, err pour les voies
ƒ
Déclaration de la variable out :
ƒ
public static PrintStream out;
println() est une méthode de la classe
PrintStream
ƒ
Depuis le JDK 5, le plus simple est d’utiliser la classe
Scanner (étudiée avant dans ce support)
car on n’a pas besoin de gérer les IOException
R. Grin
Java : entrées-sorties
123
ƒ
standard d’entrée, sortie et de messages d’erreurs
R. Grin
ƒ
On peut rediriger les voies standard des
entrées, sorties et erreurs par les méthodes
setIn(InputStream),
setOut(PrintStream) et
setErr(PrintStream) de la classe
ƒ
System
R. Grin
Java : entrées-sorties
125
Java : entrées-sorties
124
Console
A propos de System.in, out et err
ƒ
122
Petite colle !
Entrées-sorties sur clavier-écran
Scanner sc = new Scanner(System.in);
System.out.printf("%-20s", "Votre nom : ");
String nom = sc.nextLine();
System.out.printf("%-20s", "Et votre âge :
");
int age = sc.nextInt();
System.out.printf("%s a %d ans", nom, age);
Java : entrées-sorties
Depuis le JDK 6 la classe java.io.Console
permet de lire et d’écrire des caractères sur la
console (clavier – écran)
En particulier elle permet de saisir un mot de
passe tapé sur le clavier sans qu’il ne
s’affiche sur l’écran
R. Grin
Java : entrées-sorties
126
21
Exemple
Console console = System.console();
if (console = = null)
return;
console.printf("%s", "Mot de passe ? ");
char[] mdp = console.readPassword();
String mdps = new String(mdp);
console.printf("%s, %s", nom, mdps);
R. Grin
Java : entrées-sorties
Nouveau paquetage java.nio
127
R. Grin
ƒ
ƒ
ƒ
Ce paquetage reprend toute l’architecture
des classes pour les entrées/sorties
Il utilise la notion de canal (channel) et de
buffer
Il utilise les possibilités avancées du
système d’exploitation hôte pour optimiser
les entrées-sorties et offrir plus de
fonctionnalités
ƒ
ƒ
R. Grin
Java : entrées-sorties
128
Utilisation
Présentation
ƒ
Java : entrées-sorties
129
Il a été écrit pour
– permettre des entrées-sorties non
bloquantes
– améliorer les performances, en particulier
pour les serveurs fortement chargés
– bloquer des portions de fichiers
Il est un peu plus complexe à utiliser et pas
nécessaire si ces fonctionnalités ne sont pas
recherchées
Il n’est pas étudié dans ce cours
R. Grin
Java : entrées-sorties
130
Avertissement
ƒ
Classe File
ƒ
ƒ
R. Grin
Java : entrées-sorties
131
Il vaut mieux utiliser la nouvelle API NIO.2
du JDK 7 (étudiée au début de ce support)
que la classe File
La méthode toPath() de la classe File
renvoie une instance de Path ; elle peut être
utile pour faire le pont avec NIO.2
Cette section vous aidera à comprendre les
nombreuses lignes de code écrites avec les
versions précédentes du JDK
R. Grin
Java : entrées-sorties
132
22
Classe File
ƒ
ƒ
ƒ
Cette classe représente un chemin de fichier,
indépendamment du système d’exploitation
Un fichier est repéré par un chemin abstrait
composé d’un préfixe optionnel (nom d’un
disque par exemple) et de noms (noms des
Constructeurs
ƒ
Les chemins passés en premier paramètre
peuvent être des noms relatifs ou absolus
ƒ
File(String chemin)
File(String cheminParent,
String chemin)
File(File parent, String chemin)
répertoires parents et du fichier lui-même)
Attention,
ƒ
File fichier = new File("/bidule/truc");
ne lève aucune exception si /bidule/truc n’existe
ƒ
pas dans le système de fichier
R. Grin
Java : entrées-sorties
133
R. Grin
Portabilité pour les noms de fichiers
ƒ
ƒ
La classe File offre des facilités pour la
portabilité des noms de fichiers
Le caractère séparateur pour le nom d’un
fichier est donné par les constantes
File.separator (de type String) ou
ƒ
ƒ
Le caractère pour séparer des chemins (par
exemple pour classpath ou path) est donné
par File.pathSeparator et
134
Noms relatifs
File.separatorChar (de type char) (« / »
pour Unix, « \ » pour Windows)
ƒ
Java : entrées-sorties
ƒ
Les noms relatifs sont relatifs au répertoire
courant (propriété système user.dir)
Le répertoire courant est généralement le
répertoire dans lequel la JVM a été lancée
(commande java), mais est difficile à
maîtriser dans les environnements complexes
d’exécution (Java EE par exemple)
Un problème donc !
File.pathSeparatorChar
R. Grin
Java : entrées-sorties
135
est à éviter !
ƒ
ƒ
Malgré les facilités pour la portabilité
offertes par la classe File, l’utilisation de
noms de fichiers « en dur » rend souvent un
programme plus difficile à réutiliser
En effet, donner des noms absolus, et même
relatifs, nuit à la souplesse comme on le
verra dans la section suivante « Noms de
fichiers » de ce supports de cours
R. Grin
Java : entrées-sorties
Java : entrées-sorties
136
Fonctionnalités de la classe File
new File(String)
ƒ
R. Grin
137
Elle permet d’effectuer des manipulations
sur les fichiers et répertoires considérés
comme un tout (mais pas de lire ou d’écrire
le contenu) :
– lister un répertoire
– supprimer, renommer un fichier
– créer un répertoire
– créer un fichier temporaire
– connaître et positionner les droits que l’on a sur
un fichier (lecture, écriture) (depuis JDK 6)
– etc.
R. Grin
Java : entrées-sorties
138
23
Méthodes informatives
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
Méthodes pour des actions
ƒ
boolean exists()
boolean isDirectory()
boolean isFile()
boolean canRead()
boolean canWrite()
boolean canExecute()
long lastModified()
long length()
réussie)
ƒ
ƒ
ƒ
Java : entrées-sorties
boolean renameTo(File nouveau)
(true si suppression réussie)
boolean mkdir()
boolean mkdirs() (peut créer des
répertoires intermédiaires)
ƒ
ƒ
R. Grin
boolean delete() (true si suppression
139
boolean setLastModified(long
temps)
boolean setReadOnly()
R. Grin
Méthodes pour des actions
ƒ
ƒ
ƒ
ƒ
String getName() (nom terminal)
String getPath() (chemin absolu ou
relatif)
répertoire pour les fichiers temporaires,
avec un nom unique
void deleteOnExit() le fichier qui
reçoit ce message sera supprimé à la fin de
l’exécution
Java : entrées-sorties
ƒ
File getAbsoluteFile()
String getAbsolutePath()
String getParent()
File getParentFile()
ƒ
URL toURL() (de la forme file:url)
ƒ
ƒ
ƒ
141
R. Grin
Fichiers d’un répertoire
ƒ
ƒ
ƒ
ƒ
140
Méthodes pour les noms
static File
createTempFile(String prefixe,
String suffixe) crée un fichier dans le
R. Grin
Java : entrées-sorties
Java : entrées-sorties
142
Modifier les permissions
Le résultat est null si this n’est pas un
répertoire, et un tableau de taille 0 si le
listing est vide
String[] list() (noms terminaux)
ƒ
String[] list(FileNameFilter
filtre) (seulement certains fichiers)
Depuis le JDK 6, il est possible de
positionner les permissions des fichiers avec
les méthodes setWritable, setReadable,
setExecutable
File[] listFiles() (File avec des
noms relatifs ou absolus, suivant this) ;
variantes avec FileNameFilter et
FileFilter
R. Grin
Java : entrées-sorties
143
R. Grin
Java : entrées-sorties
144
24
Exemple d’utilisation de File
public boolean isLisible(String nomFichier) {
File fichier = new File(nomFichier);
if (!fichier.isFile())
return false;
return fichier.canRead();
Aucune exception
}
n’est levée si le
fichier n’existe pas
R. Grin
Java : entrées-sorties
145
25