pdf1

Transcription

pdf1
Entrées-sorties 2
Université de Nice - Sophia Antipolis
Version 2.1.4 – 8/7/13
Richard Grin
Plan de cette partie 2
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
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
Expressions régulières
R. Grin
Java : entrées-sorties
3
Généralités
ƒ
ƒ
ƒ
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
Java : entrées-sorties
4
Syntaxe des expressions régulières
ƒ
ƒ
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
Un caractère
ƒ
ƒ
ƒ
ƒ
. : 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
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
« Échapper » un caractère
ƒ
ƒ
\ : 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
Java : entrées-sorties
8
Types de caractères prédéfinis
ƒ
ƒ
\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
« Bords »
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
^ : 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
Java : entrées-sorties
10
Quantifieurs
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
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
Java : entrées-sorties
11
Glouton ou pas ?
ƒ
ƒ
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
Exemple
ƒ
ƒ
ƒ
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
Super-glouton
ƒ
ƒ
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 .++
R. Grin
Java : entrées-sorties
14
Opérateurs
ƒ
ƒ
ƒ
Si X et Y sont des expressions régulières,
XY : X suivi de Y
X|Y : X ou Y
R. Grin
Java : entrées-sorties
15
Groupes
ƒ
(X) : X, groupe « capturé »
ƒ
\n : le nième groupe capturé
ƒ
ƒ
ƒ
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
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
16
Autres possibilités (1)
ƒ
ƒ
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
Java : entrées-sorties
17
Autres possibilités (2)
ƒ
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
Méthodes de String (1)
ƒ
boolean matches(String expreg)
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
Exemple
String phrase =
"Bonjour bonhomme veux-tu un bon bonbon ?";
String phraseModifiee =
phrase.replaceAll("\\bbon(\\w+)", "mal$1");
System.out.println(phraseModifiee);
ƒ
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
Java : entrées-sorties
20
Méthode split de String
ƒ
ƒ
ƒ
String[] split(String expreg)
é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
R. Grin
Java : entrées-sorties
21
Compléments sur split
ƒ
ƒ
ƒ
ƒ
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
22
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
String[] resultat =
"c'est un test.".split("\\s");
for (int i = 0; i < resultat.length; x++)
System.out.println(resultat[i]);
ƒ
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
23
Exemples (2)
ƒ
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']+");
. . .
R. Grin
Java : entrées-sorties
24
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
Performances de String.split
ƒ
ƒ
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
Java : entrées-sorties
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
27
Classes dédiées
ƒ
ƒ
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
Java : entrées-sorties
28
Classe Pattern
ƒ
ƒ
ƒ
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
29
Méthode compile
ƒ
ƒ
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
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
31
Options de la méthode compile
ƒ
ƒ
ƒ
ƒ
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)
R. Grin
Java : entrées-sorties
32
Interface CharSequence
ƒ
Les chaînes de caractères dans lesquelles on
recherche une expression régulière sont du
type CharSequence
R. Grin
Java : entrées-sorties
33
Méthodes de Pattern
ƒ
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
34
Méthode matcher
ƒ
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
35
Classe Matcher
ƒ
ƒ
ƒ
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
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
Méthodes de la classe Matcher
ƒ
ƒ
String replaceAll(String
remplacement) renvoie une nouvelle
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
Java : entrées-sorties
38
Méthodes de la classe Matcher
ƒ
ƒ
ƒ
boolean matches() renvoie vrai si le texte en
entier correspond à l’expression régulière
boolean lookingAt() renvoie vrai si le début
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
R. Grin
Java : entrées-sorties
39
Informations sur la sous-chaîne
ƒ
ƒ
ƒ
ƒ
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
R. Grin
Java : entrées-sorties
40
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
Java : entrées-sorties
41
Méthodes pour les groupes
ƒ
ƒ
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
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
43
Fin du code
// 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));
}
R. Grin
Java : entrées-sorties
44
Affichage de l’exemple
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
R. Grin
Java : entrées-sorties
45
Remplacement
ƒ
ƒ
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
Java : entrées-sorties
46
Remplacement
ƒ
Matcher appendReplacement(StringBuffer
nouvTexte, String remplace) : ajoute les
caractères jusqu’à la fin de la précédente
correspondance (par find ou autre), son
remplacement compris
ƒ
StringBuffer appendTail(StringBuffer
nouvTexte) : ajoute les caractères qui restent
après la dernière correspondance
R. Grin
Java : entrées-sorties
47
Exemple de remplacement
// 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
Affichage de l’exemple
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
Réinitialisation
ƒ
ƒ
ƒ
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
Java : entrées-sorties
50
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
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
Recherche dans un fichier
ƒ
ƒ
ƒ
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
53
Exemple de recherche dans un fichier
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
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
StringTemplate
ƒ
ƒ
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
R. Grin
Java : entrées-sorties
56
Mise en forme
des sorties
R. Grin
Java : entrées-sorties
57
ƒ
ƒ
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
Paquetage java.text
ƒ
ƒ
ƒ
ƒ
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
SimpleDateFormat
R. Grin
Java : entrées-sorties
59
Mise en forme des nombres
import java.text.NumberFormat;
import java.util.Locale;
Locale en
. . .
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));
cours
affichera (locale courante French)
1 234 567,256
1 234 567,2
1 234 567
1,234,567.2
R. Grin
Java : entrées-sorties
60
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)
ƒ
Idem pour la partie décimale :
setMinimumFractionDigits(int n)
setMaximumFractionDigits(int n)
R. Grin
Java : entrées-sorties
61
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));
affichera (locale courante French)
01 234 567,26
01 234 567,20
1 234 567,2
1 234 567
R. Grin
Les séparateurs de
milliers et décimales
sont indépendants
de la locale en cours
Java : entrées-sorties
62
Mise en forme des 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
R. Grin
Java : entrées-sorties
63
Mise en forme spéciale de dates
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
64
Autres types de mise en forme
ƒ
NumberFormat permet aussi de mettre en
forme des valeurs monétaires et des
pourcentages avec les méthodes
getCurrencyInstance et
getPercentInstance
R. Grin
Java : entrées-sorties
65
Encore plus pour formater…
ƒ
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
ƒ
Le plus souvent ces classes sont utilisées avec
des fichiers de ressources pour internationaliser
les applications
R. Grin
Java : entrées-sorties
66
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
Exemple avec MessageFormat
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));
}
R. Grin
Java : entrées-sorties
68
Nouveautés du JDK 5
ƒ
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 »
R. Grin
Java : entrées-sorties
69
Méthodes format
ƒ
ƒ
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
ƒ
Les méthodes renvoient l’instance de la classe
(this ; on peut ainsi enchaîner)
R. Grin
Java : entrées-sorties
70
String.format
ƒ
ƒ
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
71
Méthodes printf
ƒ
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
Exemples simples
ƒ
ƒ
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
Syntaxe des formats
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
%[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
R. Grin
Java : entrées-sorties
74
Passage à la ligne
ƒ
ƒ
%n (la lettre n) fait passer à la ligne
Tient compte de la plateforme sur laquelle
on travaille
R. Grin
Java : entrées-sorties
75
Mise en forme de dates
ƒ
ƒ
ƒ
ƒ
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
76
Syntaxe complète des formats
ƒ
ƒ
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
77
Classe java.util.Formatter
ƒ
ƒ
ƒ
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
Scanner des entrées
R. Grin
Java : entrées-sorties
79
Classe java.util.Scanner
ƒ
ƒ
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
Java : entrées-sorties
80
Utilisation
ƒ
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);
ƒ
On extrait ensuite les données une à une avec
une des méthodes nextXXX :
int i = sc.nextInt();
R. Grin
Java : entrées-sorties
81
Constructeurs
ƒ
Ils peuvent prendre en paramètre une
instance de java.lang.Readable (source de
données de type caractère),
java.nio.channels.ReadableByteChannel
ƒ
(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)
R. Grin
Java : entrées-sorties
82
Délimiteurs
ƒ
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)
ƒ
On peut en indiquer d’autres avec la
méthode useDelimiter qui prend en
paramètre une expression régulière :
sc.useDelimiter("\\s*truc\\s*");
R. Grin
Java : entrées-sorties
83
Localisation
ƒ
ƒ
Une instance de Scanner utilise la locale
par défaut
On peut modifier la locale avec la méthode
useLocale
R. Grin
Java : entrées-sorties
84
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
Méthodes nextXXX
ƒ
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
Java : entrées-sorties
86
Méthodes hasNextXXX
ƒ
ƒ
ƒ
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
87
Autres méthodes
ƒ
ƒ
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
Exemple
Scanner s = new Scanner(ligne);
s.useDelimiter("\\s*;\\s*");
nom = s.next();
age = s.nextInt();
if (s.hasNextInt()) {
option = s.nextInt();
}
R. Grin
Java : entrées-sorties
89
IOException
ƒ
ƒ
ƒ
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
90
Imprimer
R. Grin
Java : entrées-sorties
91
Interfaces
ƒ
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
92
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
public static PrinterJob getPrinterJob()
ƒ
On passe ensuite à cette tâche un objet qui
représente ce que l’on veut imprimer :
– soit une instance de Printable (avec
setPrintable)
– soit une instance de Pageable (avec
setPageable)
R. Grin
Java : entrées-sorties
93
Interface Printable
ƒ
Il comporte une seule méthode
public int print(
Graphics graphics,
PageFormat pageFormat,
int pageIndex)
throws PrinterException
ƒ
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
Java : entrées-sorties
94
Méthode print
ƒ
Paramètres :
– 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)
ƒ
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
95
Exemple d’objet imprimable
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;
}
}
R. Grin
Java : entrées-sorties
96
Zone imprimable
ƒ
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
Exemple de code pour imprimer
PrinterJob tache = PrinterJob.getPrinterJob();
tache.setPrintable(objetAImprimer);
try {
doit implémenter
tache.print();
l’interface
}
Printable
catch(PrinterException e) { . . . }
R. Grin
Java : entrées-sorties
98
Choix de l’imprimante
ƒ
ƒ
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
Java : entrées-sorties
false si
l’utilisateur
a annulé
99
Choix du format de page
ƒ
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);
R. Grin
Java : entrées-sorties
100
Exemple de code
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
}
catch(PrinterException e) { . . . }
}
R. Grin
Java : entrées-sorties
101
Interface Pageable
ƒ
Elle possède 3 méthodes :
– int getNumberOfPages()
– Printable getPrintable(int numeroPage)
– PageFormat getPageFormat(int numeroPage)
R. Grin
Java : entrées-sorties
102
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
Exemple schématique avec Book
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
Java : entrées-sorties
104
Conclusion
ƒ
ƒ
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
105
APIs non standard
ƒ
ƒ
ƒ
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
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
Java : entrées-sorties
107
APIs open source et gratuites
ƒ
ƒ
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
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
http://java-source.net/open-source/pdf-libraries
R. Grin
Java : entrées-sorties
109
Isoler les entrées-sorties
R. Grin
Java : entrées-sorties
110
Pourquoi ?
ƒ
ƒ
ƒ
ƒ
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
111
Implémentation
ƒ
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
Analyse lexicale
R. Grin
Java : entrées-sorties
113
Introduction
ƒ
ƒ
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
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
R. Grin
Java : entrées-sorties
115
Avertissement
ƒ
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
Scanner
ƒ
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
Java : entrées-sorties
117
Analyse lexicale d’une chaîne
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
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
Entrées et sorties sur
clavier - écran
R. Grin
Java : entrées-sorties
120
Lecture caractère par caractère
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
121
Entrées-sorties sur clavier-écran
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.");
R. Grin
Java : entrées-sorties
122
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);
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
Petite colle !
ƒ
ƒ
ƒ
ƒ
ƒ
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
standard d’entrée, sortie et de messages d’erreurs
Déclaration de la variable out :
public static PrintStream out;
println() est une méthode de la classe
PrintStream
R. Grin
Java : entrées-sorties
124
A propos de System.in, out et err
ƒ
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
Console
ƒ
ƒ
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
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
127
Nouveau paquetage java.nio
R. Grin
Java : entrées-sorties
128
Présentation
ƒ
ƒ
ƒ
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
129
Utilisation
ƒ
ƒ
ƒ
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
Classe File
R. Grin
Java : entrées-sorties
131
Avertissement
ƒ
ƒ
ƒ
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
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
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
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. Grin
Java : entrées-sorties
134
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
File.separatorChar (de type char) (« / »
pour Unix, « \ » pour Windows)
ƒ
Le caractère pour séparer des chemins (par
exemple pour classpath ou path) est donné
par File.pathSeparator et
File.pathSeparatorChar
R. Grin
Java : entrées-sorties
135
Noms relatifs
ƒ
ƒ
ƒ
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 !
R. Grin
Java : entrées-sorties
136
new File(String)
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
137
Fonctionnalités de la classe File
ƒ
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
Méthodes informatives
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
boolean exists()
boolean isDirectory()
boolean isFile()
boolean canRead()
boolean canWrite()
boolean canExecute()
long lastModified()
long length()
R. Grin
Java : entrées-sorties
139
Méthodes pour des actions
ƒ
boolean delete() (true si suppression
réussie)
ƒ
ƒ
ƒ
boolean renameTo(File nouveau)
(true si suppression réussie)
boolean mkdir()
boolean mkdirs() (peut créer des
répertoires intermédiaires)
ƒ
ƒ
boolean setLastModified(long
temps)
boolean setReadOnly()
R. Grin
Java : entrées-sorties
140
Méthodes pour des actions
ƒ
ƒ
static File
createTempFile(String prefixe,
String suffixe) crée un fichier dans le
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
R. Grin
Java : entrées-sorties
141
Méthodes pour les noms
ƒ
String getName() (nom terminal)
ƒ
String getPath() (chemin absolu ou
relatif)
ƒ
File getAbsoluteFile()
String getAbsolutePath()
String getParent()
File getParentFile()
ƒ
URL toURL() (de la forme file:url)
ƒ
ƒ
ƒ
R. Grin
Java : entrées-sorties
142
Fichiers d’un répertoire
ƒ
ƒ
ƒ
ƒ
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)
File[] listFiles() (File avec des
noms relatifs ou absolus, suivant this) ;
variantes avec FileNameFilter et
FileFilter
R. Grin
Java : entrées-sorties
143
Modifier les permissions
ƒ
Depuis le JDK 6, il est possible de
positionner les permissions des fichiers avec
les méthodes setWritable, setReadable,
setExecutable
R. Grin
Java : entrées-sorties
144
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