Vous êtes sur la page 1sur 50

Programmation Orientée Objet

Flux et entrées/sorties
Julien Provillard

http://www.i3s.unice.fr/~provilla/poo/
julien.provillard@unice.fr
Programmation orientée objet

Objectifs
Entrées sorties
 Flux de caractères : Reader/Writer
 Flux standards
 Flux d’octets

2
Programmation orientée objet

Paquetage java.io
Système
Flux d'entrée Flux de sortie
d'exploitation
PrintWriter

Plus de 50 classes au total!


BufferedWriter
BufferedReader
FileReader FileWriter
File
Reader Writer
FileInputStream
FileOutputStream OutputStreamWriter
InputStreamReader
InputStream OutputStream

DataInputStream DataOutputStream

3
Programmation orientée objet

Les flux d'entrée/sortie


Les flux : connexions de taille limitée d'un émetteur vers un récepteur
 Écran, clavier, souris, fichiers : java.io
 À travers un socket : java.net
Sortie (e.g., Écran) sort du système
 L'émetteur sérialise les données
Entrée (e.g., Clavier) du système
 Le récepteur dé-sérialise les données
Flux de sortie vers flux d'entrée

4
Programmation orientée objet

Les fichiers : File


Notion de fichier
 Chemin absolu ou relatif
Objet de type File
 Représente le fichier situer sur le chemin /doc/fic.txt
 Le fichier n’existe pas nécessairement
 Le fichier peut être un dossier, un fichier texte ou binaire, un lien
symbolique
Exemple
File fichier = new File("/doc/fic.txt");

5
Programmation orientée objet

Les fichiers : File


Plusieurs constructeurs
 File(String chemin)
• Chemin absolu ou relatif
 File(String parent, String chemin)
• Chemin est relatif au parent
 File(File parent, String chemin)
• Chemin est relatif au parent

6
Programmation orientée objet

Les fichiers : portabilité


Constantes
 Séparateur entre deux niveaux de dossier
• final static char separatorChar;
• final static String separator;
• Représente "/", "\\", … selon le système d’exploitation

 Séparateur entre deux chemins


• final static char pathSeparatorChar;
• final static String pathSeparator;
• Représente ":", ";", … selon le système d’exploitation

7
Programmation orientée objet

Les fichiers : chemins relatifs


Les noms relatifs sont par rapport au dossier de travail
 Propriété user.dir
 Le dossier dans lequel la JVM est lancé, celui où l’on trouve les
.class
 Peut-être difficile à trouver selon l’IDE utilisé
• Utiliser plutôt des noms absolus ou relatifs par rapport à un dossier choisi par
un chemin absolu

8
Programmation orientée objet

Les fichiers : niveau système


Est-ce qu'un fichier (ou dossier) existe ?
 boolean exists()

Type de fichier
 boolean isAbsolute()
• Chemin absolu
 boolean isDirectory()
• Est un dossier ?
 boolean isFile()
• Est un fichier ?
 boolean isHidden()
• Est un fichier caché ?

9
Programmation orientée objet

Les fichiers : niveau système


Création
 boolean mkDir(), boolean mkDirs()
• Créer un dossier
 createNewFile()
• Créer un nouveau fichier (s’il n’existe pas)
 createTempFile(String, String)
 createTempFile(String, String, File)
• Créer un fichier temporaire
Destruction
 boolean delete()
• Destruction d’un fichier ou d’un dossier (true si succès)
 void deleteOnExit()
• Destruction lorsque la JVM est détruite

10
Programmation orientée objet

Les fichiers : niveau système


Droits d'accès (depuis JDK 6)
 boolean canRead()
 boolean canWrite()
 boolean canExecute()

Modifier les droits (depuis JDK6)


 boolean setReadOnly()
 boolean setWritable(boolean)
 boolean setReadable(boolean)
 boolean setExecutable(boolean)

11
Programmation orientée objet

Les fichiers : niveau système


Fichiers contenus dans un dossier
 String[] list()
 String[] list(FilenameFilter)
 File[] listFiles()
 File[] listFiles(FileFilter)
 File[] listFiles(FilenameFilter)

Conversion en URI, URL


 java.net.URL toURL()
• deprecated (toURI().toURL())
 java.net.URI toURI()
• Dépend de l’OS (escape caractères illégaux dans les URL)

12
LES FLUX DE CARACTÈRES

13
Programmation orientée objet

Flux entrants : Reader


Classe abstraite
 int read() throws IOException
 int read(char[]) throws IOException
 abstract int read(char[] buf, int deb, int nb) throws IOException
 long skip(long) throws IOException
 abstract void close() throws IOException
 synchronized void mark(int)
 synchronized void reset() throws IOException
 boolean markSupported()

14
Programmation orientée objet

Flux entrants : sous-classes


BufferedReader LineNumberReader

CharArrayReader

InputStreamReader FileReader
« abstract »
Reader
FilterReader PushbackReader

PipedReader

StringReader

15
Programmation orientée objet

Flux entrants : FileReader


Un Reader à partir d’un fichier
Constructeurs
 FileReader(String)
 FileReader(File)

Exemple
 FileReader r = new FileReader("fic.txt");

16
Programmation orientée objet

Flux entrants : BufferedReader


Permet de lire une ligne dans un Reader
 String readLine() throws IOException
Constructeurs
 BufferedReader(Reader)
 BufferedReader(Reader, int)
• Choisi la taille du buffer
• IllegalArgumentException si la taille est négative ou nulle

17
Programmation orientée objet

Lecture d’un fichier texte


public class Lecture { Ouvre un flux entrant de caractères
static public void main(String[] args) {
try {
FileReader fr = new FileReader("fic.txt");
BufferedReader br = new BufferedReader(fr);
String ligne = br.readLine();
while (ligne != null) {
System.out.println(ligne);
ligne = br.readLine();
}
br.close(); Ferme le flux
} catch (IOException ex) {
System.err.println("Erreur de lecture : " + ex);
}
}
}

18
Programmation orientée objet

Flux sortants : Writer


Classe abstraite
 Writer append(char) throws IOException
 Writer append(CharSequence) throws IOException
 Writer append(CharSequence, int deb, int fin) throws IOException
 abstract void close() throws IOException
 abstract void flush() throws IOException
 void write(char[] buf) throws IOException
 abstract void write(char[] buf, int deb, int nb) throws IOException
 void write(int) throws IOException
 void write(String) throws IOException
 void write(String, int, int) throws IOException

19
Programmation orientée objet

Flux sortants : sous-classes


BufferedWriter

CharArrayWriter

OutputStreamWriter FileWriter

« abstract »
FilterWriter
Writer

PipedWriter

StringWriter

PrintWriter

20
Programmation orientée objet

Flux sortants : FileWriter


Un Writer vers un fichier
Constructeurs
 FileWriter(String)
 FileWriter(String, boolean)
 FileWriter(File)
 FileWriter(File, boolean)

Exemple
 FileWriter w = new FileWriter("fic.txt");

21
Programmation orientée objet

Flux sortants : BufferedWriter


Permet d’écrire un saut de ligne indépendamment du système
 void newLine() throws IOException
Constructeurs
 BufferedWriter(Writer)
 BufferedWriter(Writer, int)
• Choisi la taille du buffer
• IllegalArgumentException si la taille est négative ou nulle

22
Programmation orientée objet

FileWriter et PrintWriter
 On peut diriger un flux de sortie vers un fichier (on choisit le nom du fichier)
 FileWriter fw = new FileWriter("fic.txt");
 FileWriter permet d’écrire un caractère à la fois
 void write(int unicode);
 Pour écrire une chaîne de caractère, il faut écrire tous les caractère un par un
 Pour écrire un int, il faut aussi le décomposer en caractères !
 Pas très pratique : on préfère généralement utiliser un PrintWriter :
 PrintWriter pw = new PrintWriter(fw);
 pw.print("message");

23
Programmation orientée objet

Flux sortants : PrintWriter


Permet d’écrire facilement dans un Writer
 void print(T) throws IOException
 void println(String) throws IOException
 PrintWriter printf(String, Object...)

Constructeurs
 PrintWriter(Writer)
 PrintWriter(File)
 PrintWriter(String)
 PrintWriter(OutputStream)

24
Programmation orientée objet

Écrire dans un fichier sur le disque


Il faut choisir un nom pour le fichier: fic.txt
Il faut ouvrir un flux de sortie vers le fichier :
 FileWriter fw = new FileWriter("fic.txt");
On ajoute un buffer (recommandé)
 BufferedWriter bw = new BufferedWriter(fw);
Pour manipuler des types quelconques plutôt que des caractères :
 PrintWriter pw = new PrintWriter(bw);
Pour écrire ?
 pw.println("Une ligne");
Il faut fermer le flux quand on a fini
 pw.close();
Et si il y a une erreur lors de l'ouverture, la fermeture, l'écriture ?
 Une exception est levée, il FAUT l'attraper !

25
Programmation orientée objet

Ecriture d’un fichier texte


import java.io.*;
public class Ecriture { Ouvre un flux de sortie
static public void main(String[] args) {
try {
FileWriter fw = new FileWriter("fic.txt");
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
for (int i = 0; i < args.length; i++) {
pw.println(i + " " + args[i]); Écrit dans le flux
System.out.println(args[i]); Écrit sur la sortie standard
}
pw.close(); Ferme le flux
} catch (IOException ex) { // obligatoire !
System.err.println("Erreur sur le fichier");
}
}
}
 >java Ecriture je veux écrire ça!

26
Programmation orientée objet

Ecriture d’un fichier texte


import java.io.*;
public class Ecriture { Ouvre un flux de sortie
static public void main(String[] args) {
try {
FileWriter fw = new FileWriter("fic.txt");
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
for (int i = 0; i < args.length; i++) {
pw.printf("%d %s", i, args[i]); Écrit dans le flux
pw.println(); Portable! ("\n" ne l’est pas)
System.out.println(args[i]); Écrit sur la sortie standard
}
pw.close(); Ferme le flux
} catch (IOException ex) { // obligatoire !
System.err.println("Erreur sur le fichier");
}
}
}
 >java Ecriture je veux écrire ça!

27
Programmation orientée objet

Le flux de sortie standard


Le champ statique out de la classe System est le flux de sortie standard
(par défaut, il est dirigé vers la console)
System.out.println("Bonjour");
System.out.print("Bonjour");
Deux méthodes permettent d'écrire des chaînes de caractères
 void print(String)
 void println(String)
Ces deux méthodes sont surchargées pour tous les types primitifs et le
type Object
 void print(int), void print(double), void print(Object), …
 avec un Object, la méthode toString est invoquée pour le transformer en
String.

28
Programmation orientée objet

Le flux d'erreurs standard


 System.out est utilisé pour afficher les messages d'informations
 System.err est le flux d'erreurs standard
 Il doit être utilisé pour afficher des messages d'erreurs
 Souvent les deux flux sont dirigés vers l'écran
 Dans les IDE (Eclipse, Netbeans, …), ils sont dirigés vers deux fenêtres séparées
ou sont affichés différement

public class Standard {


static public void main(String[] args) {
System.out.println("Ceci est un message normal!");
System.err.println("Ceci est un message d'erreur!");
}
}

29
Programmation orientée objet

Le flux d’entrée standard


 System.in est le flux d’entrée standard.
int read(byte[] b);
La méthode read remplit le tableau b avec les octets lus et renvoie le
nombre d'octets lus.
C’est un flux d’octets InputStream, pas de facilité d’utilisation.
Heureusement, il y a des classes enveloppantes pour traduire les octets
en chaînes de caractères : InputStreamReader.

30
Programmation orientée objet

Lire un type primitif (avant le JDK 5.0)


import java.io.*;
public class Lecture {
static public void main(String[] args) {
InputStreamReader sr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(sr);
try {
String line = br.readLine();
int nb = Integer.parseInt(line);
System.out.println(nb);
} catch (IOException ex) {
System.err.println("Erreur sur l'entrée standard");
}
}
}

Que faire si on veut plusieurs int par ligne? line.split("\\s+") ...

31
Programmation orientée objet

Lire un type primitif (après le JDK 5.0)


import java.util.Scanner;
public class Lecture {
static public void main(String[] args) {
Scanner sc = new Scanner(System.in);
int nb = sc.nextInt();
System.out.println(nb);
}
}

La classe Scanner permet de nombreux formatage et est très simple


d’utilisation.
Elle est aussi efficace qu’un BufferedReader, mais n’est pas
synchronisée.
Elle cache les erreurs d’entrée/sortie

32
Programmation orientée objet

Lecture d’un fichier texte


import java.io.*;
import java.util.Scanner; Ouvre un flux entrant de caractères
public class Lecture {
static public void main(String[] args) {
try {
int somme = 0;
Scanner sc = new Scanner(new File("fic.txt"));
while (sc.hasNextInt()) {
somme += sc.nextInt(); Lit un entier du flux
}
sc.close(); Ferme le flux
System.out.println("Somme: " + somme);
} catch (FileNotFoundException ex) {
System.err.println("Fichier non trouvé!");
}
}
}

33
LES FLUX D’OCTETS

34
Programmation orientée objet

Octets ou caractères ?
En pratique il est rare qu'on sauvegarde les données au format texte
 Ça prend trop de place !
 L'entier le plus petit est : -2147483648
 Il faut 11 caractères pour coder ce nombre !
Les fichiers courants sont mémorisés en binaire
 Suite d'octets
 Difficile à lire par l'homme
 Prend moins de place, un entier 32 bits prend 4 octets !
 Exemples : .doc, .bmp, .exe, …

35
Programmation orientée objet

Un flux de sortie binaire


La classe FileOutputStream représente les flux de sortie binaires vers
un fichier
import java.io.FileOutputStream; Ouverture
public class EcritureBinaire {
static public void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("fic.bin");
byte[] donnees = new byte[]{ 25, 60, -12, 40 };
fos.write(donnees); Écriture
fos.close(); Fermeture
} catch (IOException ex) {
System.err.println("Erreur d'écriture:" + ex);
}
}
}

36
Programmation orientée objet

Un flux d’entrée binaire


La classe FileInputStream représente les flux d'entrée binaires depuis
un fichier
import java.io.FileInputStream; Ouverture
public class LectureBinaire {
static public void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("fic.bin");
byte[] donnees = new byte[4000]; Lecture
while (fis.available() > 0) {
int nb = fis.read(donnees); // faire quelque chose avec donnees
}
fis.close(); Fermeture
} catch (IOException ex) {
System.err.println("Erreur de lecture:" + ex);
}
}
}

37
Programmation orientée objet

Compléments sur les flux


 FileOutputStream
 Méthode void flush() : vide le tampon
 Méthode int write(int o) : écrit un seul octet o
 FileInputStream
 Méthode int available()
• Donne le nombre d'octets disponibles
 Méthode int read()
• Lit un seul octet
 Méthode long skip(long n)
• Saute n octets dans la lecture;

38
Programmation orientée objet

Décorateur sur les flux binaires


Pour les flux sortants: DataOutputStream
 void writeX(X valeur) // X type primitif
 void writeChars(String chaine) // attention au surrogate
 void writeUTF(String chaine)
Pour les flux entrants: DataInputStream
 X readX() // X type primitif
 String readUTF()

39
Programmation orientée objet

Flux indépendants de l'OS : \n


 Unix : \n
 vi reconnaît \n comme un retour de ligne
 Windows : \n\r
 Notepad reconnaît \n\r comme un retour de ligne
 MacOS : \r\n
 MacWriter reconnaît \r\n comme un retour de ligne

 PrintStream ne fournit pas toujours le résultat attendu


 System.out.print ("...\n"); pas toujours correct

 Propriété système : line.separator


 System.getProperty("line.separator"); Avant java 7
 System.lineSeparator(); Depuis java 7

40
GESTION DES RESSOURCES

41
Programmation orientée objet

Automatic Resource Management


Depuis le JDK 7
 Enumération des ressources qui doivent être fermées automatiquement

try ( Déclaration des ressources à fermer ) {


// fonctionnement normal
...
}

42
Programmation orientée objet

ARM: avant
public class Lecture {
static public void main(String[] args) {
try {
FileReader fr = new FileReader("fic.txt");
BufferedReader br = new BufferedReader(fr);
String ligne = br.readLine();
while(ligne != null) {
System.out.println(ligne);
ligne = br.readLine();
}
br.close();
} catch(IOException ex) {
System.err.println("Erreur de lecture : " + ex);
}
}
}
Si une exception se produit la ressource br n’est pas fermée
43
Programmation orientée objet

ARM: avant
public class Lecture {
static public void main(String[] args) {
try {
FileReader fr = new FileReader("fic.txt");
BufferedReader br = new BufferedReader(fr);
String ligne = br.readLine();
while(ligne != null) {
System.out.println(ligne);
ligne = br.readLine();
}
} catch(IOException ex) {
System.err.println("Erreur de lecture : " + ex);
} finally { br.close(); }
}
}
Est illégal car br n’est visible que dans le bloc try !

44
Programmation orientée objet

ARM: avant
public class Lecture {
static public void main(String[] args) {
FileReader fr = new FileReader("fic.txt");
BufferedReader br = new BufferedReader(fr);
try {
String ligne = br.readLine();
while(ligne != null) {
System.out.println(ligne);
ligne = br.readLine();
}
} catch(IOException ex) {
System.err.println("Erreur de lecture : " + ex);
} finally { br.close(); }
}
}
 Est illégal car new FileReader peut lever une exception !
 2 blocs try imbriqués!

45
Programmation orientée objet

ARM: avant
public class Lecture {
static public void main(String[] args) {
try {
FileReader fr = new FileReader("fic.txt");
BufferedReader br = new BufferedReader(fr);
try {
String ligne = br.readLine();
while(ligne != null) {
System.out.println(ligne);
ligne = br.readLine();
}
} catch(IOException ex) {
System.err.println("Erreur de lecture : " + ex);
} finally { br.close(); }
} catch(IOException ex) {
System.err.println("Fichier non trouvé : " + ex);
}
}
}

46
Programmation orientée objet

ARM: avant
public class Copie {
static public void main(String[] args) {
try {
FileReader fr = new FileReader("in.txt");
BufferedReader br = new BufferedReader(fr);
try {
PrintWriter pw = new PrintWriter("out.txt");
try {
String ligne = br.readLine();
while(ligne != null) { Un bloc try/catch par ressource!
pw.println(ligne);
ligne = br.readLine();
}
} catch (IOException ex) { System.err.println(...); } finally { pw.close(); }
} catch (IOException ex) { System.err.println(...); } finally { br.close(); }
} catch (IOException ex) { System.err.println(...); }
}
} 47
Programmation orientée objet

ARM: après
public class Copie {
static public void main(String[] args) {
try (FileReader fr = new FileReader("in.txt");
BufferedReader br = new BufferedReader(fr);
PrintWriter pw = new PrintWriter("out.txt");) {
String ligne = br.readLine();
while (ligne != null) {
pw.println(ligne); Appel close automatiquement
ligne = br.readLine(); pour fermer les ressources
}
} catch (FileNotFoundException ex) {
System.err.println("Fichier non trouvé : " + ex);
} catch (IOException ex) {
System.err.println("Erreur de lecture : " + ex);
}
}
} Exécuté après l’appel à close

48
Programmation orientée objet

ARM: après
Les ressources déclarées font parties de la clause try
 Les exceptions levées sont après le catch qui suit
try (FileReader fr = new FileReader("fic.txt");
BufferedReader br = new BufferedReader(fr)) {
...
} catch (IOException ex) { ... }

Mais la méthode close() est appelée quoi qu’il arrive


 D’une façon similaire au finally
 Les variables déclarées ici doivent être d’un type qui réalise une des interfaces
AutoCloseable ou Closeable

49
Programmation orientée objet

Closeable vs AutoCloseable
 java.lang.AutoCloseable
public interface AutoCloseable {
// pas nécessairement idempotent mais recommandé
void close() throws Exception;
}
 java.io.Closeable
public interface Closeable extends AutoCloseable {
// close doit être idempotent
void close() throws IOException;
}

50

Vous aimerez peut-être aussi