Cours Java: Gestion des Flux d'E/S
Cours Java: Gestion des Flux d'E/S
JAVA II
¨ Le package [Link] comporte plusieurs sortes de flux qui peuvent être classés
suivant plusieurs critères:
¤ les flux d'entrée et les flux de sortie
¤ les flux de caractères et les flux binaires (dû au fait que java utilise l'unicode donc
les caractères sont codés sur 2 octets et non sur un seul )
¤ les flux de communication et les flux de traitement
¤ les flux avec ou sans tampon
¤ ...
¨ On commence d'abord par :
¤ les flux binaires
n les flux de communication
n les flux de traitement
¤ les flux de caractères
n les flux de communication
n les flux de traitement.
Les flux binaires
5
import [Link].*;
public class TestFileInputStream {
public static void main(String[] args) {
FileInputStream fis;
int byteLu;
try {
// creation d'un flux d'entrée ayant pour source un fichier nommé source
// cette instanciation peut lever une exception de type FileNotFound
fis = new FileInputStream("source");
// lecture des données
try {
long startChrono = [Link]();
[Link]("debut lecture");
while ((byteLu = [Link]()) != -1) ;
[Link]("fin lecture");
[Link]("durée=" + ([Link]() - startChrono));
} finally {
// fermeture du flux
[Link]();
}
} catch (FileNotFoundException ef) {
[Link]("fichier introuvable");
} catch (IOException e) {
[Link](e);
}
}
}
Les flux de traitement : Lecture
(Exemple)
12
import [Link].*;
public class TestBufferedInputStream {
public static void main(String[] args) {
BufferedInputStream bis;
int byteLu;
Byte[] buffer;
try {
// creation d'un BufferedInputStream sur un InputStream ayant pour
// source un fichier nommé source,
bis = new BufferedInputStream(new FileInputStream("source"));
// la methode available permet de connaitre le nombre de bytes qui
// pourront étre lus d'une manière non bloquante.
[Link]([Link]());
// lecture des données
[Link]("debut lecture");
try {
long startChrono = [Link]();
while ((byteLu = [Link]()) != -1) ;
[Link]("fin lecture");
[Link]("durée=" + ([Link]() - startChrono));
} finally {
// ne pas oublier de refermer le flux
[Link]();
}
} catch (FileNotFoundException ef) {
[Link]("fichier introuvable");
} catch (IOException e) {
[Link](e);
}
}
}
Les flux de sortie
13
import [Link].*;
public class ByteArrayOutputStreamExemple {
public static void main(String[] args) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int byteLu;
byte[] tab = new byte[10];
// ecriture dans le tampon
for (byte i = 0; i < 10; i++) {
[Link](i);
}
// récuperation des données contenues dans le tampon
tab = [Link]();
// affichage des données
for (int j = 0; j < 10; j++) {
[Link](tab[j]);
}
}
}
Les flux de communication: Ecriture
(Exemple)
17
import [Link].*;
class ThreadEcriture implements Runnable{
private PipedOutputStream pos;
public ThreadEcriture(PipedOutputStream pos){
[Link]=pos;
}
public void run(){
try{
for(int i=0;i<50;i++){
[Link](i);
[Link]("threadEcriture: j'ai ecrit "+i);
[Link](500);
}
}
catch(Exception e){
[Link](e);
}finally{
try{
[Link]();
}catch(IOException eio){
[Link](eio);
}
}
}
}
class ThreadLecture implements Runnable{
private PipedInputStream pis;
int i;
public ThreadLecture(PipedInputStream pis){
[Link]=pis;
}
Les flux de communication: Ecriture
(Exemple)
18
public void run(){
try{
while (( i=[Link]())!=-1) {
[Link]("threadLecture : j'ai lu "+i);
}
}catch(IOException e){
[Link](e);
}finally{
try{
[Link]();
}catch(IOException eio){
[Link](eio);
}
}
}
}
public class PipedOutputStreamExemple {
public static void main(String[] args){
try{
//création des deux pipes et leur connexion
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
ThreadEcriture tecr = new ThreadEcriture(pos);
ThreadLecture tlec = new ThreadLecture(pis);
Thread premier = new Thread(tecr);
Thread second = new Thread(tlec);
[Link]();
[Link]();
}
catch(IOException e){
[Link](e);
}
}
Les flux de traitement
19
import [Link].*;
public class BufferedOutputStreamExemple {
public static void main(String[] args) {
int i;
try {
// création des flux
BufferedInputStream in = new BufferedInputStream(new FileInputStream("source"));
try {
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("dist"));
// copie du fichier
try {
while ((i = [Link]()) != -1) {
[Link](i);
}
// vider le contenu du tampon
[Link]();
} finally {
// fermeture de out
[Link]();
}
} finally {
// fermeture de in
[Link]();
}
} catch (IOException e) {
[Link](e);
}
}
}
Les flux de traitement : Ecriture
(Exemple)
21
import [Link].*;
public class DataOutputStreamExemple {
public static void main(String[] args) {
try {
// creation du flux
DataOutputStream out = new DataOutputStream(new FileOutputStream("sortie"));
// données à ecrire
boolean test = true;
int i = 100;
try {
// ecriture des données
[Link](test);
[Link](i);
// vider le buffer
[Link]();
} finally {
// fermer le flux
[Link]();
}
} catch (IOException e) {
[Link](e);
}
}
}
Les flux de traitement : Ecriture
(Exemple)
22
import [Link].*;
public class DataInputStreamExemple {
public static void main(String[] args) {
try {
// creation du flux
DataInputStream in = new DataInputStream(new FileInputStream("sortie"));
// données à lire
boolean test;
int i;
try {
// lecture des données
test = [Link]();
i = [Link]();
} finally {
// fermer le flux
[Link]();
}
// affichage des données
[Link](test);
[Link](i);
} catch (IOException e) {
[Link](e);
}
}
}
Les flux de traitement : Ecriture
(Exemple)
23
import [Link].*;
class Personne implements Serializable{
private static final long serialVersionUID = 1L;
private int age;
private String nom;
public Personne(){
[Link]=22; [Link]="toto";
}
public String toString(){
return "nom: "+nom+"\nage: "+age;
}
}
public class ObjectOutputStreamExemple {
public static void main(String[] args) {
try {
Personne per = new Personne();
Personne personne;
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("fichierObjet"));
try {
[Link](per); // ecriture de l'objet
[Link]();
} finally {
[Link]();
}
ObjectInputStream in = new ObjectInputStream(new FileInputStream("fichierObjet"));
try {
personne = (Personne) [Link](); // lecture de l'objet
[Link](personne); // affichage
} finally {
[Link](); // fermer le flux
}
} catch (Exception e) {
[Link](e);
Les flux de caractères
24
¨ Les flux de caractères servent à manipuler des caractères, c'est-à-dire qu'il y a
échange de caractères entre le programme et une autre entité extérieur à ce dernier.
¨ Java, contrairement à beaucoup d'autres langages, utilise Unicode. Ainsi, les
caractères sont codés sur 16 bits et non sur 8. C’est pour cela que java a introduit ce
genre de flux.
¨ Ces flux servent donc à gérer les jeux de caractères (conversion possible d'un jeu à
l'autre). .
¨ Les flux de caractères dérivent de deux classes :
¤ Reader pour les flux d'entrée et
¤ Writer pour les flux de sortie.
¨ Ces deux classes sont abstraites. On ne les utilisera donc pas directement pour
obtenir un flux mais on utilisera une de leurs nombreuses classes filles.
¨ On notera la présence d'un certains nombres de méthodes, à savoir les différentes
méthodes write pour Writer et les différentes méthodes read pour Reader.
¨ Il est grand temps maintenant de détailler les différentes classes filles et leurs rôles.
Nous aborderons tout d'abord les flux d'entrée puis ceux de sortie.
Les flux d'entrée
25
import [Link].*;
public class StringReaderExemple {
public static void main(String[] args) {
try {
int i;
String chaine = "toto va à l'école";
StringReader sr = new StringReader(chaine); // creation du flux
// lecture et affichage des données
while ((i = [Link]()) != -1) {
[Link]((char) i);
}
} catch (IOException e) {
[Link](e);
}
}
}
Les flux de communication: Lecture
(Exemple)
28
import [Link].*;
public class FileReaderExemple {
public static void main(String[] args) {
try {
int i;
// creation du flux
FileReader fr = new FileReader("source");
try {
// lecture et affichage des données
while ((i = [Link]()) != -1) {
[Link]((char) i);
}
} finally {
[Link]();
}
} catch (IOException e) {
[Link](e);
}
}
}
Les flux de traitement
29
¨ Ils permettent de réaliser un traitement sur les données lues par les flux de
communication
¨ Ils se composent des classes :
¤ InputStreamReader:
n Cette classe permet de transformer un flux de données binaires en un flux de
caractères.
n Elle est très utile lorsque le tampon ou l'encodage par défaut de FileReader ne
conviennent pas.
n Elle possède un constructeur qui prend en paramètres un flux d'entrée de données
binaires et un Charset (objet servant à définir l'encodage à utiliser).
n La méthode read() lit le nombre nécessaire d'octets constituant un caractère.
¤ BufferedReader:
n Cette classe permet l'emploi d'un tampon (dont on peut spécifier la taille) lors de la
lecture d'un flux de caractères.
n Elle est très utile pour améliorer la performance de l'opération de lecture.
n Son emploi est analogue à celui de BufferedInputStream.
¤ LineNumberReader:
n sous-classe de BufferedReader, elle en hérite donc l'utilisation d'un tampon et permet en
plus de lire ligne par ligne (tout en les comptant) grâce à la méthode readLine().
Les flux de traitement : Lecture
(Exemple)
30
import [Link].*;
public class LineNumberReaderExemple {
public static void main(String[] args) {
try {
String ligneLue;
// creation du flux
LineNumberReader lnr = new LineNumberReader(new FileReader("source"));
try {
// lecture et affichage des données
while ((ligneLue = [Link]()) != null) {
System. [Link](ligneLue);
}
} finally {
// libération des ressources
[Link]();
}
} catch (IOException e) {
System. [Link](e);
}
}
}
Les flux de sortie
31
import [Link].*;
public class BufferedWriterExemple1 {
public static void main(String[] args) {
try {
String ligne;
// creation des flux
BufferedReader in = new BufferedReader(new FileReader("source"));
// lecture et copie des données
try {
BufferedWriter out = new BufferedWriter(new FileWriter("dist"));
try {
while ((ligne = [Link]()) != null) {
[Link](ligne);
// insérer un saut de ligne d'une manière portable
[Link]();
}
[Link](); // vider le buffer
} finally {
// fermeture de out
[Link]();
}
} finally {
[Link]();
}
} catch (IOException e) {
[Link](e);
}
}
}
Récapitulation sur les flux
35
ByteArrayInputStream CharArrayReader
ByteArrayOutputStream CharArrayWriter
La mémoire
StringBufferInputStream StringReader
StringWriter
FileInputStream FileReader
Un fichier
FileOutputStream FileWriter
Méthode Rôle
boolean canRead() Indiquer si le fichier peut être lu
boolean canWrite() Indiquer si le fichier peut être modifié
boolean createNewFile() Créer un nouveau fichier vide
Créer un nouveau fichier dans le répertoire par défaut des
File createTempFile(String, String) fichiers temporaires. Les deux arguments sont le nom et le
suffixe du fichier
File createTempFile(String, String, Créer un nouveau fichier temporaire. Les trois arguments
File) sont le nom, le suffixe du fichier et le répertoire
Détruire le fichier ou le répertoire. Le booléen indique le
boolean delete()
succès de l'opération
deleteOnExit() Demander la suppression du fichier à l'arrêt de la JVM
boolean exists() Indique si le fichier existe physiquement
Gestion des répertoires et des
fichiers : Classe File
38
Méthode Rôle
String getAbsolutePath() Renvoyer le chemin absolu du fichier
String getPath Renvoyer le chemin du fichier
boolean isAbsolute() Indiquer si le chemin est absolu
boolean isDirectory() Indiquer si le fichier est un répertoire
boolean isFile() Indiquer si l'objet représente un fichier
long length() Renvoyer la longueur du fichier
String[] list() Renvoyer la liste des fichiers et répertoires contenus dans le répertoire
boolean mkdir() Créer le répertoire
Créer le répertoire avec création des répertoires manquants dans
boolean mkdirs()
l'arborescence du chemin
boolean renameTo() Renommer le fichier
Gestion des répertoires et des
fichiers : Classe File
39
0
100
.....
900
Les fichiers à accès direct : position du
curseur (Exemple)
44
500
La classe [Link]
45
//import [Link];
public class ConsoleExemple {