Vous êtes sur la page 1sur 58

Le paquet des

entrées/sorties en

Rajae El Ouazzani

2014-2015
Le paquet des E/S

2014-2015 2
Présentation [1]
 Une entrée/sortie consiste en un échange de données entre le
programme et une autre source, par exemple la mémoire, un fichier,
le programme lui-même.
 Java emploie ce qu'on appelle un stream (flux). Celui-ci joue le rôle
de médiateur entre la source des données et sa destination.

Source de données: Stream/Flux Destination de données:


fichier 1 fichier 2

2014-2015 3
Suite
 Toute opération sur les E/S doit suivre le schéma suivant:
 ouverture du flux E/S,
 opération de lecture/écriture,
 fermeture du flux E/S.
 Java décompose les objets traitants des flux en deux catégories:
 les objets travaillant avec des flux d'entrée (in), pour la lecture du flux;
 les objets travaillant avec des flux de sortie (out), pour l'écriture de flux.

Flux de lecture: in
Source de Flux d’écriture: out Destination de
données: données:
fichier 1 fichier 2

2014-2015 4
Plan
 Section 1: La classe File
 Section 2: Les flux d’octets
 Les classes File(Input/Output)Stream
 Les classes Data(Input/Output)Stream
 Section 3: Les flux de caractères
 Les classes File(Writer/Reader)
 Les classes (Input/Output)Stream(Reader/Writer)
 Les classes Buffered(Reader/Writer)
 Section 4: La sérialisation
 Les classes Object(Input/Output)Stream
2014-2015 5
Section 1: La classe File

2014-2015 6
La classe File [1]
 La classe File encapsule les fonctionnalités de gestion de
fichier: Suppression, renommage, date de la dernière modification, etc.

2014-2015 7
Méthodes utilisées
Méthodes Rôles
Création d’un nouveau fichier vide, et renvoie vrai si le
boolean createNewFile()
nouveau fichier n’existait pas avant sa création.
boolean exists() Renvoie vrai si et seulement si le fichier existe.

String getName() Retourne le nom du fichier.

boolean isFile() Retourne vrai s’il s’agit d’un fichier et faux sinon.
String getPath() Retourne le chemin du fichier.
String getAbsolutePath() Retourne le chemin absolu

int compareTo(File pathname) Comparaison des 2 chemins


Renomme un fichier. retourne false si le file dest existe
boolean renameTo(File dest)
déjà, et le renommage n'est pas effectué.
8
Méthodes Rôles

boolean canRead() Renvoie vrai si le fichier peut être lu, et faux sinon.

boolean setReadOnly() Marque le fichier en lecture seule.

boolean canWrite() Renvoie vrai si le fichier peut être écrit, et faux sinon.
boolean canExecute() Renvoie vrai si le fichier peut être exécuté, et faux sinon.
•Retourne true si le fichier est caché. Sous Windows le
boolean isHidden() fichier est marqué "caché".
•Sous Unix le nom du fichier commence par un point.
Retourne la date de la dernière modification sous format de
long lastModified()
long. Date d = new Date(f .lastModified()) ;

boolean delete() Supprime le fichier


Supprime le fichier à la fin de l’exécution de la machine
void deleteOnExit()
virtuelle.
long length() La longueur du fichier, en octets. 9
Méthodes Rôles
Liste les lecteurs. Un pour chaque lecteur sous Windows
static File[] listRoots()
(X:) et "/" sous Unix.
Renvoie la liste des fichiers contenus dans le répertoire sous
String[] list()
forme d’un tableau de chaînes.
Retourne la liste des fichiers contenus dans le répertoire
File[] listFiles() sous forme d’un tableau de fichiers

boolean mkdir() Crée un répertoire.


Crée un répertoire, et tous ses parents nécessaires. L'appel
boolean mkdirs() de mkdir avec un File constitué de "\\" retourne false.
Exemple: "D:/CoursJava/PaquetES"

boolean isDirectory() Retourne vrai s’il s’agit d’un répertoire et faux sinon.

2014-2015 10
Chemin absolu Vs chemin relatif [6, 7]
 Un chemin absolu part de la racine /
 Un chemin relatif part de l'endroit ou l'on se trouve.

 Exemple 1: si je me trouve sur /home/Mohammed,


 le chemin absolu vers mon bureau est :
/home/Mohammed/Bureau,
 le chemin relatif est ./Bureau (ou Bureau plus simplement).

 Exemple 2: chemin d’accès à un site web:


 Chemins absolus est:
http://www.adobe.com/support/dreamweaver/contents.html
 Chemins relatifs au document: dreamweaver/contents.html). 11
Exemple
 On va créer un fichier test.txt.
 On va le mettre dans l’emplacement suivant:
D:\Mes documents\test.txt
 On va mettre le texte suivant dans le fichier:

Cours de la programmation orienté objet en java.


Pour les étudiants de la LP en informatique.
Bon courage à tous.

 On va utiliser quelques unes des méthodes présentées


précédemment.

2014-2015 12
import java.io.File; // pour utiliser l'objet File
public class Exemple {
public static void main(String[] args) {
//Création de l'objet File. Créer physiquement "test.txt"
File f = new File("E://Mes documents//test.txt");
System.out.println("Chemin absolu du fichier : " +
f.getAbsolutePath()); //D:\Mes documents/test.txt
System.out.println("Nom du fichier : " + f.getName());
//test.txt
System.out.println("Est-ce qu'il existe ? " + f.exists());
// true
System.out.println("Est-ce un fichier ? " + f.isFile());
// true
System.out.println("Est-ce un répertoire ? " +
f.isDirectory()); //fasle

2014-2015 13
System.out.println("Affichage des lecteurs à la racine du PC:");
for(File lecteur: File.listRoots()) { //c’est une méthode static
System.out.println(lecteur.getAbsolutePath());
try {
//On parcourt la liste des fichiers et répertoires
for(File fichier : lecteur.listFiles())
//S'il s'agit d'un dossier, on ajoute un "/"
System.out.print(((fichier.isDirectory()) ?
fichier.getName()+"/" : fichier.getName()));
} catch (NullPointerException e) {
//L'instruction peut générer une NullPointerException
s'il n'y a pas de sous-fichier !
}
}
}
}

2014-2015 14
Section 2: Les flux d’octets

2014-2015 15
Les flux d'octets [2]
 Les classes abstraites InputStream et OutputStream
implémentent les types de flux d'entrée (in) et de sortie (out)
dans lesquelles il est possible de lire ou d'écrire une suite d'octets.

2014-2015 16
Les objets InputStream et OutputStream [3]

2014-2015 17
Les classes File(Input/Output) Stream

2014-2015 18
Les classes File(Input/Output) Stream [2]

2014-2015 19
Explication

 La classe InputStream possède une méthode read qui lit un octet et


renvoie cet octet ou bien -1 si la fin de la source de données a été
atteinte.
 Le concepteur d'une classe concrète pour un flux d'entrée va
surcharger cette méthode pour plus de fonctionnalités.

2014-2015 20
Suite

 La classe OutputStream définit une méthode abstraite write pour


écrire un octet vers une destination.
 A l'issue d'une opération d'écriture ou de lecture dans un flux, il faut
le fermer en appelant la méthode close.

2014-2015 21
Remarques
 Si une application ouvre de nombreux flux sans prendre soin de les
fermer, elle peut épuiser les ressources du système.
 La fermeture d'un flux de sortie a aussi pour effet de vider le tampon
utilisé par le flux de sortie. Tous les caractères se trouvant en transit
dans un tampon sont émis.
 Si vous ne fermez pas un fichier, le dernier paquet d'octets risque de
ne jamais partir. Il est possible de forcer un vidage avec la méthode
flush().

2014-2015 22
Exemple
 Nous allons essayer de lire le contenu d’un fichier texte
Fichier1.txt et on va le copier dans un autre fichier Fichier2.txt.

 Le fichier "Fichier1.txt" contient le texte suivant:


Cours de JAva.

2014-2015 23
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
// on peut utiliser le package java.io.*
public class CopierFichier {
public static void main(String[] args) {
//FileNotFoundException traite le cas où test1.txt n'existe pas
//IOException traite le cas où il y'a une erreur lors des
méthodes read / write
try{
File f1= new File("Fichier1.txt");
FileInputStream fis= new FileInputStream(f1);
// on doit créer physiquement "test1.txt“
File f2= new File("Fichier2.txt");
FileOutputStream fos= new FileOutputStream(f2);

2014-2015 24
int n = 0; /* On affecte le résultat de la lecture à la
variable n. Quand c'est fini n vaut -1 */
//Tant que il y’a des valeurs dans Fichier1.txt, on boucle.
while ((n = fis.read()) != -1) {
fos.write(n); // On écrit dans Fichier2.txt
// On l’affiche au format char et en code décimal
System.out.println(n + "(" + (char) n + ")");
}
System.out.println("Copie terminée !");
// fermeture des 2 flux
if (fis != null) fis.close();
if (fos != null) fos.close();
} // fermeture de try
catch (FileNotFoundException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
} // fermeture de main
} // fermeture de la classe

2014-2015 25
Exécution
 Si le fichier "Fichier1.txt" contient le texte suivant:
Cours de JAva.
 Alors, le programme affiche le résultat suivant:
67(C) 74(J)
111(o) 65(A)
117(u) 118(v) Cela
114(r) 97(a) exprime un
115(s) 46(.) retour à la
32( ) 13( ligne
100(d) )
101(e) 10(
32( ) )
Copie terminée !

26
Les classes Data(Input/Output)Stream

2014-2015 27
Les objets InputStream et OutputStream [3]
 Les classes Data(Input/Output)Stream dérivent des 2 classes abstraites
Filter(Input/Output)Stream.
 4 classes filles dérivent de Filter(Input/Output)Stream.

2014-2015 28
Les classes Data(Input/Output)Stream
 Les classes qui dérivent de Filter(Input/Output)Stream sont:
 Data(Input/Output)Stream: offre la possibilité de lire
directement des variables de types primitifs (double, char, int,
etc.)ainsi que les chaines de caractères (String) grâce à des
méthodes comme readDouble(), readInt(), etc.
 Buffered(Input/Output)Stream: cette classe permet d'avoir un
tampon à disposition dans la lecture/écriture du flux. En gros, les
données vont tout d'abord remplir le tampon, et dès que celui-ci
est plein, le programme accède aux données.
 PushbackInputStream: permet de remettre un octet ou
caractère déjà lu dans le flux entrant.
 LineNumber(Input/Output)Stream: cette classe offre la
possibilité de récupérer le numéro de la ligne lue à un instant T.
29
Hiérarchie des classes
 Ces 4 classes prennent en paramètre une instance dérivant des
classes Input/OutputStream.
 Exemple:
File f= new File("test.txt");
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis= new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
//Ou en condensé :
DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(
new File("test.txt")))); 30
Les méthodes des classes Data(Input/Output)Stream

 Les classes DataInputStream et DataOutputStream sont spécialisées


dans la lecture/écriture de tous les types de base de Java.

2014-2015 31
Exemple
import java.io.File;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream; import java.io.DataOutputStream;
import java.io.FileInputStream; import java.io.FileOutputStream;
import java.io.IOException;
public class Exemple {
public static void main(String[] args) throws IOException {
try{
File f=new File("test.txt");

DataInputStream dis =new DataInputStream(new


BufferedInputStream(new FileInputStream(f)));

DataOutputStream dos=new DataOutputStream(new


BufferedOutputStream(new FileOutputStream(f)));

32
//Nous allons écrire plusieurs types primitifs
dos.writeBoolean(true);
dos.writeByte(100);
dos.writeChar('C');
dos.writeDouble(12.05);
dos.writeFloat(100.52f);
dos.writeInt(1024);
dos.writeLong(123456789654321L);
dos.writeShort(2);
dos.close();

33
//On récupère maintenant les données !
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readDouble());
System.out.println(dis.readFloat());
System.out.println(dis.readInt());
System.out.println(dis.readLong());
System.out.println(dis.readShort());
dis.close();
}catch(IOException e){}
}
}

2014-2015 34
Résultat
true
100
C
12.05
100.52
1024
123456789654321
2

2014-2015 35
Remarques
 Comme les flux d'octets conviennent mal aux traitements
d'informations codées en Unicode (on se souvient qu'Unicode
utilise deux octets par caractère), il a été introduit une hiérarchie
de classes spéciale pour le traitement de caractères.
 Ces classes héritent des superclasses abstraites spéciales Reader
et Writer qui possèdent des méthodes d'écriture et de lecture
reconnaissant les caractères Unicode en deux octets et non des
caractères d'un seul octet.

2014-2015 36
Section 3: Les flux de caractères

2014-2015 37
Les flux de caractères [5]
 Depuis la version 1.1, les classes Reader et Writer ont été rajoutées
au package java.io. La hiérarchie des nouvelles classes suit de près
celle des existantes déjà dans la version 1.0 . La principale raison de
cette modification est le besoin de gérer les caractères
internationaux sur 16 bits aux lieu des 8 bits de l'ancienne version.

 Ces classes Reader et Writer sont également des classes abstraites et


manipulent comme unité de base le caractère (et non pas l'octet).

 Les classes Reader et Writer, tout comme les classes InputStream et


OutputStream, sont les classes de base à partir desquelles toutes les
autres classes sont dérivées.
2014-2015 38
Suite [4, 5]
 La classe BufferedReader dérive de la classe Reader.
 BufferedReader a la méthode readLine() qui permet de lire une
ligne de texte à travers un tampon, et ce pour des besoins de
performances. Cette méthode renvoie null lorsqu'il ne reste plus
d'entrées.

2014-2015 39
Suite [4]
 Le constructeur de BufferedReader demande en entrée un objet de
type Reader, InputStreamReader ou FileReader.

40
Les classes File(Reader/Writer)
 Les classes travaillant avec des flux (Stream) utilisent des flux
binaires.

 Les classes File(Reader/Writer) présentes dans le package java.io,


servent à lire et écrire des données dans un fichier texte.

2014-2015 41
Exemple 1 : FileReader/Writer
import java.io.File; import java.io.IOException;
import java.io.FileReader; import java.io.FileWriter;
public class Exemple {
public static void main(String[] args) throws IOException {
try{
File file = new File("test.txt");
FileWriter fw = new FileWriter(file);
FileReader fr = new FileReader(file);
String str = "Salam à tous!\n";
fw.write(str); //On écrit la chaîne
fw.close(); //On ferme le flux
int i = 0; str = "";
while((i = fr.read()) != -1) //Lecture des données
str += (char)i;
System.out.println(str); //Affichage
fr.close();
}catch(IOException e){}
} 42
}
Exemple 2: (Input/Output)Stream(Reader/Writer)
import java.io.File;
import java.io.FileInputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;import java.io.OutputStreamWriter;
public class Exemple {
public static void main(String[] args) throws IOException {
try{
File file = new File("test.txt");
InputStreamReader rd = new InputStreamReader(new
FileInputStream(file));
OutputStreamWriter wrt = new OutputStreamWriter(new
FileOutputStream(file));
// La suite reste inchangée
}catch(IOException e){}
}
}
43
Exemple 3: Buffered(Reader/Writer)
import java.io.File; import java.io.IOException;
import java.io.BufferedReader; import java.io.BufferedWriter;
import java.io.FileReader; import java.io.FileWriter;
public class Exemple {
public static void main(String[] args) throws IOException {
try{
File file = new File("test.txt");
BufferedWriter bw = new BufferedWriter(new
FileWriter(file));
BufferedReader br = new BufferedReader (new
FileReader(file));
String str = "Salam à tous!\n";
bw.write(str); //On écrit la chaîne
bw.close(); //On ferme le flux
System.out.println(br.readLine()); //Lecture et affichage
br.close();
}catch(IOException e){}
}
44
}
Exemple 4: Buffered(Reader/Writer)
import java.io.File; import java.io.IOException;
import java.io.BufferedReader; import java.io.BufferedWriter;
import java.io.FileInputStream; import java.io.FileOutputStream;
import java.io.InputStreamReader;import java.io.OutputStreamWriter;

public class Exemple {


public static void main(String[] args) throws IOException {
try{
File file = new File("test.txt");
BufferedReader rd = new BufferedReader(new
InputStreamReader(new FileInputStream(file)));
BufferedWriter wrt = new BufferedWriter(new
OutputStreamWriter(new FileOutputStream(file)));
// La suite reste inchangée
}catch(IOException e){}
}
} 45
Section 4: La sérialisation

2014-2015 46
La sérialisation et Object(Input/Output)Stream
 La sérialisation est l’opération de sauvegarder des objets dans des
fichiers.

2014-2015 47
Exemple
import java.io.Serializable;
public class Personne implements Serializable{
private String nom, prenom;
private int age;
public Personne(String nom, String prenom, int age) {
this.nom = nom;
this.prenom = prenom;
this.age = age;
}
String getNom(){ return nom;}
String getPrenom(){ return prenom;}
int getAge(){ return age;}
public String toString(){
return "La personne est: " +getNom()+" "+getPrenom()+",
son age est: " +getAge();
}
} 2014-2015 48
Remarques
 L’interface Serializable n'a pas de méthode à redéfinir, on l’appelle
une interface marqueur.

 En implémentant cette interface dans un objet, Java sait que cet


objet peut être sérialisé.

 En revanche, si une superclasse implémente l'interface Serializable,


ses classes dérivées seront considérés comme sérialisables.

2014-2015 49
Atelier sur la sérialisation
 Nous allons réaliser les opérations suivantes :
 nous allons créer trois objets de la classe Personne;
 nous allons les sérialiser dans un fichier "personne.txt" ;
 nous allons ensuite ajouter un nouveau attribut à la classe
personne et le sérialiser.

2014-2015 50
import java.io.File; import java.io.IOException;
import java.io.BufferedInputStream; import java.io.BufferedOutputStream;
import java.io.FileInputStream; import java.io.FileOutputStream;
import java.io.ObjectInputStream; import java.io.ObjectOutputStream;

public class Serialisation{


public static void main(String[] args) throws IOException,
ClassNotFoundException {

File file = new File("personne.txt");


try{
ObjectOutputStream oos =new ObjectOutputStream(new
BufferedOutputStream( new FileOutputStream(file)));
//Ecriture dans le fichier
oos.writeObject(new Personne("Ahamdi", "Marouane", 20));
oos.writeObject(new Personne("Karroumi", "Mohammed", 21));
oos.writeObject(new Personne("Nadiri", "Asmae", 20));
oos.close(); // fermeture du flux

51
ObjectInputStream ois =new ObjectInputStream(new
BufferedInputStream( new FileInputStream(file)));
System.out.println("Affichage des personnes:");
System.out.println(((Personne)ois.readObject()).toString());
System.out.println(((Personne)ois.readObject()).toString());
System.out.println(((Personne)ois.readObject()).toString());
ois.close(); // fermeture du flux
}
catch(IOException e1){
e1.printStackTrace();
}
catch(ClassNotFoundException e2){
e2.printStackTrace();
}
}
}

52
Résultat
Affichage des personnes:
La personne est: Ahamdi Marouane, son age est: 20
La personne est: Karroumi Mohammed, son age est: 21
La personne est: Nadiri Asmae, son age est: 20

2014-2015 53
 Le code précédent permet d’enregistrer les 3 objets créés dans le
fichier "personne.txt".
 Supposons qu’on veut ajouter un nouveau attribut nationalité aux
objets de la classe Personne.
1) Créer une nouvelle classe Nationalité avec le nouveau attribut
nationalité et des constructeurs.
2) Modifier la définition de la classe Personne en ajoutant l’attribut
nationalité, en ajoutant un accesseur à l’attribut nationalité et en
mettant à jour la méthode toString().
3) Rendre le nouveau attribut sérialisable/non sérialisable.

2014-2015 54
Étape 1: création de la nouvelle classe
public class Nationalite {
private String nationalité;

public Nationalite(){
nationalité = "Marocaine";
}
public Nationalite(String nationalité){
this.nationalité = nationalité;
}
}

2014-2015 55
Étape 2: Ajouter une nationalité à la classe
import java.io.Serializable;
public class Personne implements Serializable{
private String nom, prenom;
private int age;
private Nationalite nationalité;
public Personne(String nom, String prenom, int age) {
this.nom = nom;
this.prenom = prenom;
this.age = age;
this. nationalité = new Nationalite();
}
String getNom(){ return nom;}
String getPrenom(){ return prenom;}
int getAge(){ return age;}
Nationalite getNationalité(){ return nationalité;}
public String toString(){
return "La personne est: " +getNom()+" "+getPrenom()+", son age
est: " +getAge()+ ", a la nationalité: " +getNationalité();
} 56
}
Étape 3: Rendre le nouveau attribut
sérialisable/non sérialisable
 Le code précédent génère une erreur de compilation parce que
l’objet nationalité n’est pas sérialisable.
 On peut résoudre le problème par l’une des 2 solutions:
 Rendre l’objet nationalité sérialisable (mémorisable): on
implémente l'interface sérialisable dans la classe Nationalité.
 Rendre l’objet nationalité non sérialisable (non mémorisable):
Spécifier dans la classe Personne que la variable nationalité
n'a pas à être sérialisée. Il suffit de déclarer cette variable:
transient. Lors de la déclaration des attributs de la classe:
private transient Nationalite nationalité;

2014-2015 57
Références
[1]: http://fr.openclassrooms.com/informatique/cours/apprenez-a-programmer-
en-java/les-flux-d-entree-sortie
[2]:http://bet-
nafet.ma/expert/Java/Tutoriels/ExceptionsFluxFichiers/FluxFichiers.htm#
[3]: http://www.okipa.be/notes-java/entree-sortie/article/les-flux-d-entree-sortie-
en-java
[4]: http://www.okipa.be/notes-java/entree-sortie/article/les-flux-d-entree-sortie-
en-java
[5]: http://pages.univ-nc.nc/~touraivane/Java/node16.html
[6]: http://forum.ubuntu-fr.org/viewtopic.php?id=427272
[7]: http://helpx.adobe.com/fr/dreamweaver/using/linking-navigation.html

2014-2015 58

Vous aimerez peut-être aussi