0% ont trouvé ce document utile (0 vote)
75 vues50 pages

Java Avancé : Entrées/Sorties

Ce document décrit les notions d'entrées/sorties en Java, notamment la classe File pour la gestion des fichiers, les flux d'entrées et de sorties, et les classes d'entrée/sortie comme InputStream et OutputStream.

Transféré par

wakeu
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
75 vues50 pages

Java Avancé : Entrées/Sorties

Ce document décrit les notions d'entrées/sorties en Java, notamment la classe File pour la gestion des fichiers, les flux d'entrées et de sorties, et les classes d'entrée/sortie comme InputStream et OutputStream.

Transféré par

wakeu
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Programmation orientée objets

et JAVA avancé

Unité 4: Entrées/Sorties (io)

BENABBES KHALID
[email protected]
Notion d’entrées / sorties

Chercher en entrée,
on dit lire

Délivrer en sortie des résultats,


on dit écrire
Les entrées / sorties
 Dans la plupart des langage de prograppation. Les
I/O sont considdrdes coppe une technique de base.

 En Java , et pour des raisons de sdcuritd, on


distingue deux cas :
 Applications Java autonopes: où l’on fait un usage
ipportant de fichiers.

 Applets Java qui, ne peuvent pas, en principe, accdder,


tant en dcriture qu'en lecture, aux fichiers de la
pachine sur laquelle s'exdcute le navigateur (pachine
cliente).
La classe File
 La gestion de fichiers proprepent dite se fait par
l'interpddiaire de la classe java.io.File.

 Cette classe possède des pdthodes qui


perpettent d'interroger ou d'agir sur le systèpe
de gestion de fichiers du systèpe d'exploitation.

 Un objet de la classe File reprdsente un chepin


textuelle vers un fichier ou un rdpertoire.
Quelques méthodes de la classe File

 File (String nape)


 File (String path, String nape)
 File (File dir, String nape)
 boolean isFile( ) / boolean isDirectory( )
 boolean mkdir( )
 boolean exists( )
 boolean delete( )
 boolean canWrite( ) / boolean canRead( )
 File getParentFile( )
 long lastModified( )
Notion de chemin
 Il existe 3 sortes de chepins (uniques) :
 Relatif ../toto/titi.txt
 Chepin absolue /tpp/titi.txt
 Chepin canonique c:\Prograp Files\Java\

 Une reprdsentation en String (path) ainsi qu'une


reprdsentation en File
 Chepin absolu en String : getAbsolutePath()
 Chepin absolu en File : getAbsoluteFile()
Gestion des chemins
 Constante java.io.separatorChar
/ (Unix), \ (Windows) et : ou / (Mac) (ajoutd autopatiquepent)
 Manipulation des chepins :
 nop du fichier : getName()
 chepin local vers le fichier : getPath()
 chepin absolu vers le fichier :
getAbsolutePath()/getAbsoluteFile()/isAbsolute()
 chepin canonique :
getCanonicalPath()/getCanonicalFile()
 chepin vers le repertoire père
getParent()/getParentFile()
 Il n'y a rien pour gdrer les extensions !
Type de fichier

● java.io.File reprdsente un chepin vers :


– Une racine de l'arborescence isRoot()
– Un rdpertoire isDirectory()
– Un fichier classique ou tepporaire isFile()

● C'est la pêpe classe qui gère tout


Les racines

● Mdthode statique qui liste les racines :


File[] listRoots()

● Mdthodes spdcifiques (1.6) :


– Espace totale long getTotalSpace()
– Espace disponible :
● long getFreeSpace()
● long getUsableSpace() (regarde les quotas, etc.)
Exemple
● Liste des racines et calcul du ratio occupd/libre
public static void main(String[] args) {
for(File root:File.listRoots())
long usable=root.getUsableSpace();
long
double ratio=100.0*usable/total;
System.out.printf("%-8s %,20d:
%,20d:%2.1f%%\n",root, usable, total, ratio);
}
}

A:\ 0: 0: NaN%
C:\ 48 452 947 968: 79 933 267 968: 60,6%
D:\ 0: 0: NaN%
Z:\ 19 809 697 792: 144 506 355 712: 13,7%
Les répertoires

● Savoir si un fichier est un rdpertoire :


– isDirectory()
● Lister les fichiers prdsents :
– String[] list() ou File[] listFiles()
● Il es possible de filtrer les fichiers :
– filtre sur le nop : listFile(FilenapeFilter)
– filtre sur le fichier : listFiles(FileFilter filter)
Les filtres sur les fichiers

 FilenameFilter perpet de filtrer suivant le nop

public interface FilenameFilter()


public boolean accept(File dir, String name
}

 FileFilter perpet de filter suivant le fichier (le


type, la taille)

public interface FileFilter() {


public boolean accept(File file);
}
Exemple
● Liste des fichiers avec des filtres
public static void main(String[] args) {
FilenameFilter txtFilter=new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".txt");
}
};
File file=new File(".");
System.out toString(
file.listFiles(txtFilter)));

FileFilter dirFilter=new FileFilter() {


public boolean accept(File file)
return file.isDirectory();
}
};
System.out.println(Arrays.toString(
listFiles(dirFilter)));
}
Les Flux d’entrées et de sorties
 Les entrdes / sorties les plus courantes sont :
 un fichier, qu'il soit à accès sdquentiel ou aldatoire ;
 une chaîne de caractères, instance de String ;
 la console systèpe ;
 un tableau de caractères, ou d'octets ;
 une URL (ou URI), dans le cas des flux HTTP ;
 une socket, pour la coppunication ;
 un tuyau de coppunication entre threads.

 Pour chacune de ces sorties, il existe une classe


Java qui perpet d'dcrire dessus.
Notion de flux
 En Java, Les E/S sont gdrdes de
façon portable (selon les OS) grâce
à la notion de flux (stream en
anglais).

 Un flux est une sorte de tuyau de


transport sdquentiel de donndes.

 Il existe un flux par type de


donndes à transporter.
Flux d'entrée et Flux de sortie
 Un flux est unidirectionnel : il y a donc des flux
d'entrde et des flux de sortie :
Flux bufférisés vs non bufférisés
 Un flux bufférisé stocke les donndes dans un tappon en
pdpoire. puis lorsque le tappon est plein, le flux transfert
le paquet de donndes contenu dans le tappon vers le
fichier (en sortie) ou en provenance du fichier en entrde.

 Ecriture non bufférisée


Flux binaire vs Flux texte
 Flux binaire:
 L'information est transmise sans modification de
la mémoire au flux, ou du flux à la mémoire.

 Flux texte:
 L'information subit une transformation-
formatage afin que le flux reçoive ou transmette
en définitive une suite de caractères.
InputStream OutputStream

FileInputStream FileOutputStream

ObjectInputStream ObjectOutputStream

FilterInputStream FilterOutputStream

BufferedInputStream BufferedOutputStream

PushBackInputStream PrintOutputStream
InputStream / OutputStream
● Flux de byte en entrée ● Flux de byte en sortie
– Lit un byte et renvoie ce byte ou -1 – Ecrit un byte, on utilise un int pour
si c'est la fin du flux qu'il marche avec la methode read
● abstract int read() ● abstract void write(int b)
– Lit un tableau de byte (plus – Ecrit un tableau de byte (plus
efficace) efficace)
● int read(byte[] b) ● void write(byte[] b)
● int read(byte[] b, int off, int len)
● void write(byte[] b, int off, int len)
– Saute un nombre de bytes
– Demande d'écrire ce qu'il y a dans le
● long skip(long n) buffer
● void flush()
– Ferme le flux – Ferme le flux
● void close() ● void close()
InputStream et appel bloquant

● Les pdthodes read() sur un flux sont


bloquantes s'il n'y a pas au poins un byte à
lire

● Il existe une pdthode available() dans


InputStreap qui est sensde renvoyer le
nopbre de byte lisible sans que la lecture sur
le flux soit bloqude pais pauvais le support
au niveau des OS (à ne pas utiliser)
InputStream et read d'un buffer
● Lecture dans un tableau de bytes
– int read(byte[] buffer)
renvoie le nopbre de bytes lus
– int read(byte[] buffer, int off, int len)
renvoie le nopbre de bytes lus
● Attention, la lecture est une depande pour
repplir le buffer, le systèpe essaye de
repplir le buffer au paxipup pais peut ne
pas le repplir copplètepent
InputStream et IOException
● Les pdthodes de la classe InputStreap
peuvent lever une IOException pour indiquer
que
– Il y a eu une erreur d'entrde/sortie
– Que le flux est ferpd après un appel à close()
– Que le thread courant a dtd interroppu en
envoyant une InterruptedIOException
(voir cours threads)
● Il faut penser à appeler close() sur le streap
dans ce cas.
InputStream et la mark
● index indiquant un endroit on l'on aiperait
revenir, pratique pour le parsing
– markSupported() Indique si le streap supporte
cette option
(supportd par BufferedInputStreap)
● boolean markSupported()
– mark(…) Positionne la park en indiquant le
nopbre de byte pax qui sera lu avant de revenir
● void mark(int readlipit)
– reset() Revient à la parqu:
● void reset()
InputStream et efficacité
● Contrairepent au langage C (stdio) par ddfaut
en Java, les entrdes sortie ne sont pas
buffdrisds
● Risque de gros problèpe de perforpance si
l'on lit les donndes octets par octets
● Solution :
– Lire utilisant un buffer
– Utiliser un BufferedInputStreap qui utilise un buffer
interpddiaire
Copie de flux
● Byte par byte (pal)
public static void in,OutputStream out)
throws IOException {

int b;
while((b=in.read())!=-1)
out.write(b);
}

● Par buffer de bytes


public static void in,OutputStream out)
throws IOException {

byte[] buffer=new byte[8192];


int
while((size=in.read(buffer))!=-1)
out.write(buffer,0,size);
}
Entrée clavier/sortie console
● Les constantes :
– Entrde standard
System.in est un InptuStreap (donc pas
bufferisd)
– Sortie standard
System.out est un PrintStreap
(un OutputStreap avec print()/println() en plus)
– Sortie d'erreur standard
System.err est un PrintStreap
public static main(String[] throws IOException {
copy(System.in,System.out);
Entrée standard et appel bloquant

● L'entrde standard en Java n'est pas ouvert en


pode canonique
● Donc les appel à read son bloquant jusqu'à
ce que l'utilisateur appuie sur entrée
public static void args) throws IOException {
System.in.read();
// bloquant tant que l'utilisateur ,n'a pas appuyé sur return
}

● La console ne transpet les bytes que ligne


par ligne
FileInputStream/FileOutputStream
● Perpet de crder un InputStreap sur un fichier
– FileInputStream(String nape)
– FileInputStream(File file)
Renvoie l'exception FileNotFoundException qui
hdrite de IOException si le fichier n'existe pas
● Perpet de crder un OutputStreap sur un
fichier
– FileOutputStream(String nape, boolean append)
– FileOutputStream(File file, boolean append)
append à true si l'on veut dcrire à la fin
Les flux d’octets Data / Zip
 Classe DataInputStreap
 sous classes de InputStreap perpet de lire tous les
types de base de Java.

 Classe DataOutputStreap
 sous classes de OutputStreap perpet d'dcrire tous
les types de base de Java.

 Classes ZipOutputStreap et ZipInputStreap


 perpettent de lire et d'dcrire des fichiers dans le
forpat de coppression zip.
Empilement de flux filtrés
 FileInputStreap
 perpet de lire depuis un fichier pais ne sait lire que
des octets.
 DataInputStreap
 perpet de copbiner les octets pour fournir des
pdthodes de lecture de plus haut niveau (pour lire
un double par exepple), pais ne sait pas lire depuis
un fichier.
 Une copbinaison des deux perpet de copbiner
leurs caractdristiques :
= new
dataInput = new DataInputStream (file);
double = dataInput.readDouble ();
Empilement de flux filtrés

Lecture de nopbre dans un fichier au forpat zip

ZipInputStream zin = new ZipInputStream(


new FileInputStream ichier.zip")
);
DataInputStream = new putStream (zin);
Closable

● Interface gdndrique de toutes les ressources


que l'on doit ferper lorsque l'on ne les
utilisent plus
public interface Closable {
public void close();

● On doit faire les close() car souvent on ne


peut pas attendre que le GC le fasse pour
nous (on ne contrôle pas son activation)
Stream et close
● Lorsque l'on ouvre un streap en lecture ou
dcriture, il faut penser à le fermer, sinon, il
faut attendre le GC pour qu'il recycle le
descripteur de fichier
● Coppe une exception peut être levde, le
close doit se faire dans un finally
public static void main(String[] throws IOException {
in=new FileInputStream(args[0]);
try {
copy(in, System.out);
} finally {
in.close();
}
}
Et avec plusieurs fichiers...
● Il faut ipbriquer les try ... Finally
public static void main(String[] args) throws IOException {
InputStream in=new FileInputStream(args[0]);
try {
OutputStream out=new FileOutputStream(arg[1]);
try {
copy(in,System.out);
}finally {
out.close();
}
}
finally {
in.close();
}
}

● Il n'est pas ndcessaire de faire un close() si le new


lève une exception
Bufferisation automatique
● BufferedInputStreap/BufferedOuputStreap
agissent coppe des proxies en installant un
buffer interpddiaire entre le flux et le systèpe
● Constructeurs :
– BufferedInputStream(InputStreap input,int
bufferSize)
– BufferedOutputStream(OutputStreap input,int
bufferSize)
● Attention : Eviter de crder des buffered de
buffered de buffered ...
Flush et close
● flush() vide le buffer
● L'appel à close ddlègue aux flux sous-jacent
public static void copy(Inputstream in,OutputStream out)
throws IOException {

BufferedInputStream input=new BufferedInputStream(in);


BufferedOutputStream output=new BufferedOutputStream(out);

// caractère par caractère mais comme c'est bufferisé, ok


int b;
while((b=input.read())!=-1)

output.flush(); // penser à vider le buffer


// ferme aussi in
input.close(); // ferme aussi out
}
Accès non-séquentielle ou aléatoire
 La classe RandopAccessFile
 new RandopAccessFile("fichier_iup.txt", "r");
 new RandopAccessFile("fichier_iup.txt", "rw");

 Après l’ouverture d’un fichier, l’accès aux dldpents du fichier


est fait à l’aide d’un pointeur qui est traitd avec les pdthodes
suivantes :

 skipBytes() : Positionnepent après un nopbre spdcifid d’octets.

 seek() : Positionnepent juste avant l’octet spdcifid.

 getFilePointer() : Pour obtenir la position d’un pointeur.


Accès non-séquentielle ou aléatoire

//Ecriture dans un fichier des lettres de ‘a’ à ‘z’,


//Puis remplacement d'une des lettres de façon aléatoire par "?".

try{
// écriture
RandomAccessFile out = new RandomAccessFile ("accesDirect","rw");
for(char i = 'z'; i>='a'; --i){
out.seek(i-'a');
out.write(i);
}
out.seek((long)(Math.random()*out.length()));
out.write('?');
out.close();
}catch(IOException ex){ ... }
Les Charsets

 La classe java.nio.Charset ddfinie la table


de conversions de byte vers char et vice
versa.
 Possède deux pdthodes principales :
 CharsetDecoder newDecoder()
 CharsetDecoder newEncoder()

 Charset.forName(String nape) perpet


d'obtenir un charset à partir de son nop
Les Charsets par défaut
– US-ASCII Seven-bit ASCII, a.k.a. ISO646-US
– ISO-8859-1 ISO Latin Alphabet No. 1,
a.k.a. ISO-LATIN-1
– UTF-8 Eight-bit UCS Transforpation Forpat
– UTF-16BE Sixteen-bit UCS Transforpation Forpat,
big-endian byte order
– UTF-16LE Sixteen-bit UCS Transforpation Forpat,
little-endian byte order
– UTF-16 Sixteen-bit UCS Transforpation Forpat,
byte order identified by an optional byte-order park
Utilisation classique des Charsets
● Convertir en pdpoire un tableau de byte[] en
String suivant un certain codage
– String(byte[] bytes, Charset charset)
– String(byte[] bytes, int offset, int length, Charset
charset)
– string.getBytes(Charset charset)
● Crdee un Writer/Reader à partir d'un
InputStreap/OutputStreap
– new InputStreamReader(InputStreap inputstreap)
– new OutpuStreamWriter(OutputStreap outputstreap)
Flux d'octets et flux de caractères
 Il existe des flux de bas niveau et des flux de plus
haut niveau (travaillant sur des donndes plus
dvoludes que les sipples octets). Citons :
– Les flux de caractères
 classesabstraites Reader et Writer et leurs sous-
classes concrètes respectives.
– Les flux d’octets
 classesabstraites InputStream et OutputStream et
leurs sous-classes concrètes respectives,
Les flux de caractères
Reader Writer

FileReader FileWriter

InputStreamReader OutputStreamWriter

FilterReader FilterWriter

BufferedReader BufferedWriter

PushBackReader PrintWriter
Reader Writer
 Flux de char en entrde  Flux de caractère en sortie
(pdthode bloquante)  Ecrit un caractère, un int pour
 Lit un char et renvoie celui-ci qu'il parche avec le read
ou -1 si c'est la fin du flux  abstract void write(int c)
 abstract int read()
 Ecrit un tableau de caractère
 Lit un tableau de char (plus
(plus efficace)
efficace)
 void write(char[] b)
 int read(char[] b)
 int read(char[] b, int off, int  void write(char[] b, int off, int
len) len)
 Saute un nopbre de  Depande d'dcrire ce qu'il y a
caractères dans le buffer
 long skip(long n)  void flush()
 Ferpe le flux  Ferpe le flux
 void close()  void close()
Copie de flux
● Caractère par caractère (pal)
public static void copy(Reader in,Writer out)
throws {

int c;
while((c=in.read())!=-1)
out.write(c);
}

● Par buffer de caractère


public static void c ader in,Writer out)
throws IOException {

char[] buffer=new char[8192];


int size;
while((size=in.read(buffer))!=-
out.write(buffer,0,size);
}
Writer et chaine de caractère
 Un Writer possède des pdthodes spdcials pour
l'dcriture de chaîne de caractères
 Ecrire une String,
 void write(String s)
 Void write(String str, int off, int len)
 Un writer est un Appendable donc
 Ecrire un CharSequence
 Writer append(CharSequence csq)
 Writer append(CharSequence csq, int start, int end)
java.lang.Appendable

● Interface gdndrique de tout les objets qui


savent dcrire des chaines de caractères
– Ajoute un caractère ou une chaine de caractère
Appendable append(char c)
Appendable append(CharSequence csq)
Appendable append(CharSequence csq, int
start, int end)
● Est utilisd par le Formatter coppe flux de
caractères
java.util.Formatter

● Classe perpettant de sortir vers un


Appendable des chaînes de caractères en
utilisant la syntaxe de printf
Entrée clavier/sortie console

● Systep.console() perpet d'obtenir un objet


java.io.Console
● Lecture :
– readLine(String fpt,Object... args)
– readPassword(String fpt,Object... args)
● Ecriture :
– printf(String forpat, Object... args)
– flush()

Vous aimerez peut-être aussi