 |
 |
11) Le système d’E/S de Java |
|
 |
|
Texte original |
 |
Traducteur :
Armel Fortun |
|
 |
|
Ce chapitre contient
10 pages
1
2
3
4
5
6
7
8
9
10
|
|
|
 |
 |
 |
 |
 |
 |
|
 |
05.07.01 - version 0.4 : - Ajout des tags de séparation des pages pour le site. 10.05.2001 - Version 0.3 : - Corrections (propositions de Jean-Pierre VIDAL) orth, trad. 25.04.2001 - Version 0.2 : - Mise en forme du code html (titres-hx[verdana], paragraphes-p[Georgia], code-blockquote). Traducteur : - Armel FORTUN Texte original : -Thinking in Java, 2nd edition, Revision 10 © 2000 by Bruce Eckel
|
 |
 |
 |
11: The Java I/O System
|
 |
11: Le système d'E/S de Java
|
 |
 |
 |
Creating a good input/output (I/O)
system is one of the more difficult tasks for the language
designer.
|
 |
La création d'un bon système d'entrée/sortie, pour le designer du
langage, est l'une des tâches les plus difficiles.
|
 |
 |
 |
This is evidenced by the number of
different approaches. The challenge seems to be in covering all eventualities.
Not only are there different sources and sinks of I/O that you want to
communicate with (files, the console, network connections), but you need to talk
to them in a wide variety of ways (sequential, random-access, buffered, binary,
character, by lines, by words, etc.).
|
 |
Cette difficulté est mise en évidence par le nombre d'approches
différentes. Le défi semblant être dans la couverture de toutes les éventualités. Non seulement il
y a de nombreuses sources et de réceptacles d'E/S avec lesquelles vous voudrez communiquer
(fichiers, la console, connections réseau), mais vous voudrez converser avec elles de manières très
différentes (séquentielle, accès-aléatoire, mise en mémoire tampon, binaire, caractère, par lignes,
par mots, etc.).
|
 |
 |
 |
The Java library designers attacked this
problem by creating lots of classes. In fact, there are so many classes for
Java’s I/O system that it can be intimidating at first (ironically, the
Java I/O design actually prevents an explosion of classes). There was also a
significant change in the I/O library after Java 1.0,
when the original byte-oriented library was supplemented with
char-oriented, Unicode-based I/O classes. As a result there are a fair
number of classes to learn before you understand enough of Java’s I/O
picture that you can use it properly. In addition, it’s rather important
to understand the evolution history of the I/O library, even if your first
reaction is “don’t bother me with history, just show me how to use
it!” The problem is that without the historical perspective you will
rapidly become confused with some of the classes and when you should and
shouldn’t use them.
|
 |
Les designers de bibliothèque Java ont attaqué ce problème en créant de
nombreuses classes. En fait, il y a tellement de classes pour le système d'E/S de Java que cela
peut être intimidant au premier abord (ironiquement, le design d'E/S de Java prévient maintenant
d'une explosion de classes). Il y a eu aussi un changement significatif dans la bibliothèque d'E/S
après Java 1.0, quand la bibliothèque orientée-byte d'origine a été complétée par
des classes d'E/S de base Unicode orientées-char. La conséquence étant qu'il vous
faudra assimiler un bon nombre de classes avant de comprendre suffisamment la représentation de
l'E/S Java afin de l'employer correctement. De plus, il est plutôt important de comprendre
l'évolution historique de la bibliothèque E/S, même si votre première réaction est « me prenez
pas la tête avec l'historique, montrez moi seulement comment l'utiliser ! » Le problème est
que sans un point de vue historique vous serez rapidement perdu avec certaines des classes et
lorsque vous devrez les utiliser vous ne pourrez pas et ne les utiliserez pas.
|
 |
 |
 |
This chapter will give you an
introduction to the variety of I/O classes in the standard Java library and how
to use them.
|
 |
Ce chapitre vous fournira une introduction aux diverses classes d'E/S que
comprend la bibliothèque standard de Java et la manière de les employer.
|
 |
 |
 |
The File
class
|
 |
La classe File
|
 |
 |
 |
Before getting into the classes that
actually read and write data to streams, we’ll look a utility provided
with the library to assist you in handling file directory
issues.
|
 |
Avant d'aborder les classes qui effectivement lisent et écrivent des
données depuis des streams (flux), nous allons observer un utilitaire fournit avec la bibliothèque
afin de vous assister lors des traitements de répertoire de fichiers.
|
 |
 |
 |
The File class has a deceiving
name—you might think it refers to a file, but it doesn’t. It can
represent either the name of a particular file or the names of a
set of files in a directory. If it’s a set of files, you can ask for the
set with the list( ) method, and this returns an array of
String. It makes sense to return an array rather than one of the flexible
container classes because the number of elements is fixed, and if you want a
different directory listing you just create a different File object. In
fact, “FilePath” would have been a better name for the class. This
section shows an example of the use of this class, including the associated
FilenameFilter
interface.
|
 |
La classe File possède un nom décevant — vous pouvez
penser qu'elle se réfère a un fichier, mais pas du tout. Elle peut représenter soit le nom
d'un fichier particulier ou bien les noms d'un jeu de fichiers dans un dossier. Si il
s'agit d'un jeu de fichiers, vous pouvez faire appel a ce jeu avec la méthode
list(), et celle-ci renverra un tableau de String. Il est de bon
sens de renvoyer un tableau plutôt qu'une classe containeur plus flexible parce que le nombre
d'éléments est fixé, et si vous désirez le listing d'un répertoire différent vous créez simplement
un autre objet File. En fait, « CheminDeFichier ou FilePath » aurait été
un meilleur nom pour cette classe. Cette partie montre un exemple d'utilisation de cette classe,
incluant l'interface associée FilenameFilter.
|
 |
 |
 |
A directory lister
|
 |
Lister un répertoire
|
 |
 |
 |
Suppose you’d like to see a
directory listing. The File object can be listed in two ways. If you call
list( ) with no arguments, you’ll get the full list that the
File object contains. However, if you want a restricted list—for
example, if you want all of the files with an extension of
.java—then you use a “directory filter,” which is a
class that tells how to select the File objects for
display.
|
 |
Supposons que vous désirez voir le listing d'un répertoire. L'objet
File peut être listé de deux manières. Si vous appelez list()
sans arguments, vous obtiendrez la liste complète du contenu de l'objet File .
Pourtant, si vous désirez une liste restreinte — par exemple, cependant si vous voulez tous
les fichiers avec une extension .java — à ce moment là vous utiliserez un
« filtre de répertoire », qui est une classe montrant de quelle manière sélectionner les
objets File pour la visualisation.
|
 |
 |
 |
Here’s the code for the example.
Note that the result has been effortlessly sorted (alphabetically) using the
java.utils.Array.sort( ) method and the AlphabeticComparator
defined in Chapter 9:
|
 |
Voici le code de l'exemple. Notez que le résultat a été trié sans effort
(par ordre alphabétique) en utilisant la méthode java.utils.Array.sort() et
l'AlphabeticComparator défini au Chapitre 9 :
|
 |
 |
 |
//: c11:DirList.java
// Displays directory listing.
import java.io.*;
import java.util.*;
import com.bruceeckel.util.*;
public class DirList {
public static void main(String[] args) {
File path = new File(".");
String[] list;
if(args.length == 0)
list = path.list();
else
list = path.list(new DirFilter(args[0]));
Arrays.sort(list,
new AlphabeticComparator());
for(int i = 0; i < list.length; i++)
System.out.println(list[i]);
}
}
class DirFilter implements FilenameFilter {
String afn;
DirFilter(String afn) { this.afn = afn; }
public boolean accept(File dir, String name) {
// Strip path information:
String f = new File(name).getName();
return f.indexOf(afn) != -1;
}
} ///:~
|
 |
//: c11:DirList.java // Affiche le listing d'un répertoire. import java.io.*; import java.util.*; import com.bruceeckel.util.*;
public class DirList { public static void main(String[] args) { File path = new File("."); String[] list; if(args.length == 0) list = path.list(); else list = path.list(new DirFilter(args[0])); Arrays.sort(list, new AlphabeticComparator()); for(int i = 0; i < list.length; i++) System.out.println(list[i]); } }
class DirFilter implements FilenameFilter { String afn; DirFilter(String afn) { this.afn = afn; } public boolean accept(File dir, String name) { // Information du chemin de répertoire : String f = new File(name).getName(); return f.indexOf(afn) != -1; } } ///:~
|
 |
 |
 |
The DirFilter class
“implements” the interface FilenameFilter. It’s
useful to see how simple the FilenameFilter interface
is:
|
 |
La classe DirFilter « implémente »
l'interface FilenameFilter. Il est utile de voir combien est
simple l'interface FilenameFilter :
|
 |
 |
 |
public interface FilenameFilter {
boolean accept(File dir, String name);
}
|
 |
public interface FilenameFilter { boolean accept(File dir, String name); }
|
 |
 |
 |
It says all that this type of object does
is provide a method called accept( ). The whole reason behind the
creation of this class is to provide the accept( ) method to the
list( ) method so that list( ) can “call
back” accept( ) to determine which file names should be
included in the list. Thus, this technique is often referred to as a
callback or sometimes a
functor (that is, DirFilter is a functor
because its only job is to hold a method) or the
Command Pattern.
Because list( ) takes a FilenameFilter object as its
argument, it means that you can pass an object of any class that implements
FilenameFilter to choose (even at run-time) how the list( )
method will behave. The purpose of a callback is to provide flexibility in the
behavior of code.
|
 |
Cela veut dire que ce type d'objet ne s'occupe que de fournir une méthode
appelée accept(). La finalité derrière la création de cette classe est de fournir
la méthode accept() à la méthode list() de telle manière que
list() puisse « rappeler » accept() pour déterminer
quelle noms de fichiers doivent êtres inclus dans la liste. Ainsi, cette technique fait souvent
référence à un rappel automatique ou parfois à un [functor] (c'est à dire,
DirFilter est un functor parce que sa seule fonction est de maintenir une méthode)
ou la Command Pattern (une entité, ensemble de caractéristiques, de commandes). Parce que
list() prend un objet FilenameFilter comme argument, cela veut
dire que l'on peut passer un objet de n'importe quelle classe implémentant
FilenameFilter afin de choisir (même lors de l'exécution) comment la méthode
list() devra se comporter. L'objectif d'un rappel est de fournir une flexibilité
dans le comportement du code.
|
 |
 |
 |
DirFilter shows that just because
an interface contains only a set of methods, you’re not restricted
to writing only those methods. (You must at least provide definitions for all
the methods in an interface, however.) In this case, the DirFilter
constructor is also created.
|
 |
DirFilter montre que comme une interface
ne peut contenir qu'un jeu de méthodes, vous n'êtes pas réduit a l'écriture seule de ces méthodes.
(Vous devez au moins fournir les définitions pour toutes les méthodes dans une interface, de toutes
les manières.) Dans ce cas, le constructeur de DirFilter est aussi
créé.
|
 |
 |
 |
The accept( ) method must
accept a File object representing the directory that a particular file is
found in, and a String containing the name of that file. You might choose
to use or ignore either of these arguments, but you will probably at least use
the file name. Remember that the list( ) method is calling
accept( ) for each of the file names in the directory object to see
which one should be included—this is indicated by the boolean
result returned by accept( ).
|
 |
La méthode accept() doit accepter un objet
File représentant le répertoire où un fichier en particulier se trouve, et un
String contenant le nom de ce fichier. Vous pouvez choisir d'utiliser ou ignorer
l'un ou l'autre de ces arguments, mais vous utiliserez probablement au moins le nom du fichier.
Rappelez vous que la méthode list() fait appel à accept() pour
chacun des noms de fichier de l'objet répertoire pour voir lequel doit être inclus — ceci est
indique par le résultat booléen renvoyé par accept().
|
 |
 |
 |
To make sure the element you’re
working with is only the file name and contains no path information, all you
have to do is take the String object and create a File object out
of it, then call getName( ), which strips away all the path
information (in a platform-independent way). Then accept( ) uses the
String class
indexOf( ) method to see if the search string afn appears
anywhere in the name of the file. If afn is found within the string, the
return value is the starting index of afn, but if it’s not found
the return value is -1. Keep in mind that this is a simple string search and
does not have “glob” expression wildcard matching—such as
“fo?.b?r*”—which is much more difficult to
implement.
|
 |
Pour être sûr que l'élément avec lequel vous êtes en train de travailler
est seulement le nom du fichier et qu'il ne contient pas d'information de chemin, tout ce que vous
avez a faire est de prendre l'objet String et de créer un objet
File en dehors de celui-ci, puis d'appeler getName(), qui éloigne
toutes les informations de chemin (dans l'optique d'une indépendance vis-à-vis de la plate-forme).
Puis accept() utilise la méthode indexOf() de la classe
String pour voir si la chaîne de caractères recherchée afn
apparaît n'importe où dans le nom du fichier. Si afn est trouvé à l'intérieur de
la chaîne de caractères, la valeur retournée sera l'indice de départ d'afn, mais
si il n'est pas trouvé la valeur retourné sera - 1. Gardez en tête que ce n'est qu'une simple
recherche de chaîne de caractères et qui ne possède pas d'expression « globale » de
comparaison d'assortiment — comme « fo?.b?r* » — qui est beaucoup plus
difficile a réaliser.
|
 |
 |
 |
The list( ) method returns an
array. You can query this array for its length and then move through it
selecting the array elements. This ability to easily pass an array in and out of
a method is a tremendous improvement over the behavior of C and
C++.
|
 |
La méthode list() renvoie un tableau. Vous pouvez
interroger ce tableau sur sa longueur et puis vous déplacer d'un bout a l'autre de celui-ci en
sélectionnant des éléments du tableau. Cette aptitude de passer facilement un tableau dedans et
hors d'une méthode est une amélioration immense supérieure au comportement de C et C++.
|
 |
 |
 |
Anonymous inner classes
|
 |
Les classes internes anonymes
|
 |
 |
 |
This example is ideal for rewriting using
an
anonymous
inner class (described in Chapter 8). As a first cut, a method filter( )
is created that returns a reference to a
FilenameFilter:
|
 |
Cet exemple est idéal pour une réécriture utilisant une classe interne
anonyme (décrite au Chapitre 8). Tout d'abord, une méthode filter() est créé
retournant une référence à un FilenameFilter :
|
 |
 |
 |
//: c11:DirList2.java
// Uses anonymous inner classes.
import java.io.*;
import java.util.*;
import com.bruceeckel.util.*;
public class DirList2 {
public static FilenameFilter
filter(final String afn) {
// Creation of anonymous inner class:
return new FilenameFilter() {
String fn = afn;
public boolean accept(File dir, String n) {
// Strip path information:
String f = new File(n).getName();
return f.indexOf(fn) != -1;
}
}; // End of anonymous inner class
}
public static void main(String[] args) {
File path = new File(".");
String[] list;
if(args.length == 0)
list = path.list();
else
list = path.list(filter(args[0]));
Arrays.sort(list,
new AlphabeticComparator());
for(int i = 0; i < list.length; i++)
System.out.println(list[i]);
}
} ///:~
|
 |
//: c11:DirList2.java // Utilisation de classes internes anonymes. import java.io.*; import java.util.*; import com.bruceeckel.util.*;
public class DirList2 { public static FilenameFilter filter(final String afn) { // Creation de la classe anonyme interne : return new FilenameFilter() { String fn = afn; public boolean accept(File dir, String n) { // Strip path information: String f = new File(n).getName(); return f.indexOf(fn) != -1; } }; // Fin de la classe anonyme interne. } public static void main(String[] args) { File path = new File("."); String[] list; if(args.length == 0) list = path.list(); else list = path.list(filter(args[0])); Arrays.sort(list, new AlphabeticComparator()); for(int i = 0; i < list.length; i++) System.out.println(list[i]); } } ///:~
|
 |
 |
 |
Note that the argument to
filter( ) must be
final. This is required
by the anonymous inner class so that it can use an object from outside its
scope.
|
 |
Notez que l'argument de filter() doit être
final. Ceci est requis par la classe interne anonyme pour qu'elle puisse utiliser
un objet hors de sa portée.
|
 |
 |
 |
This design is an improvement because the
FilenameFilter class is now tightly bound to DirList2. However,
you can take this approach one step further and define the anonymous inner class
as an argument to list( ), in which case it’s even
smaller:
|
 |
Cette conception est une amélioration puisque la classe
FilenameFilter est maintenant fortement liée à DirList2.
Cependant, vous pouvez reprendre cette approche et aller plus loin en définissant la classe anonyme
interne comme un argument de list(), auquel cas c'est encore plus léger
:
|
 |
 |
 |
//: c11:DirList3.java
// Building the anonymous inner class "in-place."
import java.io.*;
import java.util.*;
import com.bruceeckel.util.*;
public class DirList3 {
public static void main(final String[] args) {
File path = new File(".");
String[] list;
if(args.length == 0)
list = path.list();
else
list = path.list(new FilenameFilter() {
public boolean
accept(File dir, String n) {
String f = new File(n).getName();
return f.indexOf(args[0]) != -1;
}
});
Arrays.sort(list,
new AlphabeticComparator());
for(int i = 0; i < list.length; i++)
System.out.println(list[i]);
}
} ///:~
|
 |
//: c11:DirList3.java // Construction de la classe anonyme interne «sur-place ». import java.io.*; import java.util.*; import com.bruceeckel.util.*;
public class DirList3 { public static void main(final String[] args) { File path = new File("."); String[] list; if(args.length == 0) list = path.list(); else list = path.list(new FilenameFilter() { public boolean accept(File dir, String n) { String f = new File(n).getName(); return f.indexOf(args[0]) != -1; } }); Arrays.sort(list, new AlphabeticComparator()); for(int i = 0; i < list.length; i++) System.out.println(list[i]); } } ///:~
|
 |
 |
 |
The argument to main( ) is
now final, since the anonymous inner class uses args[0]
directly.
|
 |
L'argument de main() est maintenant
final, puisque la classe anonyme interne utilise directement
args[0].
|
 |
 |
 |
This shows you how anonymous inner
classes allow the creation of quick-and-dirty classes to solve problems. Since
everything in Java revolves around classes, this can be a useful coding
technique. One benefit is that it keeps the code that solves a particular
problem isolated together in one spot. On the other hand, it is not always as
easy to read, so you must use it
judiciously.
|
 |
Ceci vous montre comment les classes anonymes internes permettent la
création de classes rapides-et-propres pour résoudre des problèmes. Étant donné que tout en Java
tourne autour des classes, cela peut être une technique de code utile. Un avantage étant que cela
garde le code permettant de résoudre un problème particulier isolé dans un même lieu. D'un autre
côté, cela n'est pas toujours facile à lire, donc vous devrez l'utiliser judicieusement.
|
 |
 |
 |
Checking for and creating directories
|
 |
Vérification et création de répertoires
|
 |
 |
 |
The File class is more than just a
representation for an existing file or directory. You can also use a File
object to create a new directory
or an entire directory path if it doesn’t exist. You can also look at the
characteristics of files (size,
last modification date, read/write), see whether a File object represents
a file or a directory, and delete a file. This program shows some of the other
methods available with the File class (see the HTML documentation from
java.sun.com for the full set):
|
 |
La classe File est bien plus qu'une représentation d'un
fichier ou d'un répertoire existant. Vous pouvez aussi utiliser un objet File pour
créer un nouveau répertoire ou un chemin complet de répertoire si ils n'existent pas. Vous pouvez
également regarder les caractéristiques des fichiers (taille, dernière modification, date,
lecture/écriture), voir si un objet File représente un fichier ou un répertoire,
et supprimer un fichier. Ce programme montre quelques unes des méthodes disponibles avec la classe
File (voir la documentation HTML à java.sun.com pour le jeu complet)
:
|
 |
 |
 |
//: c11:MakeDirectories.java
// Demonstrates the use of the File class to
// create directories and manipulate files.
import java.io.*;
public class MakeDirectories {
private final static String usage =
"Usage:MakeDirectories path1 ...\n" +
"Creates each path\n" +
"Usage:MakeDirectories -d path1 ...\n" +
"Deletes each path\n" +
"Usage:MakeDirectories -r path1 path2\n" +
"Renames from path1 to path2\n";
private static void usage() {
System.err.println(usage);
System.exit(1);
}
private static void fileData(File f) {
System.out.println(
"Absolute path: " + f.getAbsolutePath() +
"\n Can read: " + f.canRead() +
"\n Can write: " + f.canWrite() +
"\n getName: " + f.getName() +
"\n getParent: " + f.getParent() +
"\n getPath: " + f.getPath() +
"\n length: " + f.length() +
"\n lastModified: " + f.lastModified());
if(f.isFile())
System.out.println("it's a file");
else if(f.isDirectory())
System.out.println("it's a directory");
}
public static void main(String[] args) {
if(args.length < 1) usage();
if(args[0].equals("-r")) {
if(args.length != 3) usage();
File
old = new File(args[1]),
rname = new File(args[2]);
old.renameTo(rname);
fileData(old);
fileData(rname);
return; // Exit main
}
int count = 0;
boolean del = false;
if(args[0].equals("-d")) {
count++;
del = true;
}
for( ; count < args.length; count++) {
File f = new File(args[count]);
if(f.exists()) {
System.out.println(f + " exists");
if(del) {
System.out.println("deleting..." + f);
f.delete();
}
}
else { // Doesn't exist
if(!del) {
f.mkdirs();
System.out.println("created " + f);
}
}
fileData(f);
}
}
} ///:~
|
 |
//: c11:MakeDirectories.java // Démonstration de l'usage de la classe File pour // creer des répertoire et manipuler des fichiers. import java.io.*;
public class MakeDirectories { private final static String usage = "Usage:MakeDirectories path1 ...\n" + "Creates each path\n" + "Usage:MakeDirectories -d path1 ...\n" + "Deletes each path\n" + "Usage:MakeDirectories -r path1 path2\n" + "Renames from path1 to path2\n"; private static void usage() { System.err.println(usage); System.exit(1); } private static void fileData(File f) { System.out.println( "Absolute path: " + f.getAbsolutePath() + "\n Can read: " + f.canRead() + "\n Can write: " + f.canWrite() + "\n getName: " + f.getName() + "\n getParent: " + f.getParent() + "\n getPath: " + f.getPath() + "\n length: " + f.length() + "\n lastModified: " + f.lastModified()); if(f.isFile()) System.out.println("it's a file"); else if(f.isDirectory()) System.out.println("it's a directory"); } public static void main(String[] args) { if(args.length < 1) usage(); if(args[0].equals("-r")) { if(args.length != 3) usage(); File old = new File(args[1]), rname = new File(args[2]); old.renameTo(rname); fileData(old); fileData(rname); return; // Sortie de main } int count = 0; boolean del = false; if(args[0].equals("-d")) { count++; del = true; } for( ; count < args.length; count++) { File f = new File(args[count]); if(f.exists()) { System.out.println(f + " exists"); if(del) { System.out.println("deleting..." + f); f.delete(); } } else { // N'existe pas if(!del) { f.mkdirs(); System.out.println("created " + f); } } fileData(f); } } } ///:~
|
 |
 |
 |
In fileData( ) you can see
various file investigation methods used to display information about the file or
directory path.
|
 |
Dans fileData() vous pourrez voir diverses méthodes
d'investigation de fichier employées pour afficher les informations sur le fichier ou sur le chemin
du répertoire.
|
 |
 |
 |
The first method that’s exercised
by main( ) is
renameTo( ), which
allows you to rename (or move) a file to an entirely new path represented by the
argument, which is another File object. This also works with directories
of any length.
|
 |
La première méthode pratiquée par main() est
renameTo(), laquelle vous permet de renommer (ou déplacer) un fichier vers un
nouveau chemin de répertoire signalé par l'argument, qui est un autre objet File.
Ceci fonctionne également avec des répertoire de n'importe quelle longueur.
|
 |
 |
 |
If you experiment with the above program,
you’ll find that you can make a directory path of any complexity because
mkdirs( ) will do
all the work for you.
|
 |
Si vous expérimentez le programme ci-dessus, vous découvrirez que vous
pouvez créer un chemin de répertoire de n'importe quelle complexité puisque
mkdirs() s'occupera de tout.
|
 |
 |
 |
Input and
output
|
 |
Entrée et sortie
|
 |
 |
 |
I/O libraries often use the abstraction
of a stream, which represents any data source or sink as an object
capable of producing or receiving pieces of data. The stream hides the details
of what happens to the data inside the actual I/O device.
|
 |
Les bibliothèques d'E/S utilisent souvent l'abstraction d'un flux [stream],
qui représente n'importe quelle source ou réceptacle de données comme un objet capable de produire
et de recevoir des parties de données. Le flux cache les détails de ce qui arrive aux données dans
le véritable dispositif d'E/S.
|
 |
 |
 |
The Java library classes for I/O are
divided by input and output, as you can see by looking at the online Java class
hierarchy with your Web browser. By inheritance, everything derived from the
InputStream or Reader classes have basic methods called
read( ) for reading a single byte or array of bytes. Likewise,
everything derived from OutputStream or Writer classes have basic
methods called write( ) for writing a single byte or array of bytes.
However, you won’t generally use these methods; they exist so that other
classes can use them—these other classes provide a more useful interface.
Thus, you’ll rarely create your stream object by using a single class, but
instead will layer multiple objects together to provide your desired
functionality. The fact that you create more than one object to create a single
resulting stream is the primary reason that Java’s stream library is
confusing.
|
 |
Les classes de la bibliothèque d'E/S Java sont divisées par entrée et
sortie, comme vous pouvez le voir en regardant en ligne la hiérarchie des classes Java avec votre
navigateur Web. Par héritage, toute dérivée des classes InputStream ou
Reader possède des méthodes de base nommées read() pour lire un
simple byte ou un tableau de bytes. De la même manière, toutes les dérivés des classes
OutputStream ou Writer ont des méthodes basiques appelées
write() pour écrire un seul byte ou un tableau de bytes. Cependant, de manière
générale vous n'utiliserez pas ces méthodes ; elles existent afin que les autres classes puissent
les utiliser — ces autres classes ayant des interfaces plus utiles. Ainsi, vous créerez
rarement votre objet flux [stream] par l'emploi d'une seule classe, mais au lieu de cela en plaçant
les objets ensemble sur plusieurs couches pour arriver à la fonctionnalité désirée. Le fait de
créer plus d'un objet pour aboutir à un seul flux est la raison primaire qui rend la bibliothèque
de flux Java confuse.
|
 |
 |
 |
It’s helpful to categorize the
classes by their functionality. In Java 1.0, the library designers started by
deciding that all classes that had anything to do with input would be inherited
from InputStream and all classes that were associated with output would
be inherited from OutputStream.
|
 |
Il est utile de ranger les classes suivant leurs fonctionnalités. Pour Java
1.0, les auteurs de la bibliothèque commencèrent par décider que toutes les classes n'ayant rien à
voir avec l'entrée hériteraient de l'InputStream et toutes les classes qui
seraient associées avec la sortie seraient héritées depuis
OutputStream.
|
 |
 |
 |
Types of InputStream
|
 |
Les types d'InputStream
|
 |
 |
 |
InputStream’s job is to
represent classes that produce input from different sources. These sources can
be:
|
 |
Le boulot d'InputStream est de
représenter les classes qui produisent l'entrée depuis différentes sources. Ces sources peuvent
êtres :
|
 |
 |
 |
- An array of
bytes.
- A
String
object.
- A
file.
- A
“pipe,” which works like a
physical
pipe: you put things in one end
and they come out the other.
- A sequence of other
streams, so you can collect them together into a single
stream.
- Other
sources, such as an Internet connection. (This will be discussed in a later
chapter.)
|
 |
- Une série de bytes.
- Un objet String.
- Un fichier.
- Un « tuyau », lequel fonctionne comme un vrai tuyau : vous
introduisez des choses à une entrée et elles ressortent de l'autre.
- Une succession d'autres flux, que vous pouvez ainsi rassembler dans
un seul flux.
- D'autres sources, comme une connexion internet. (Ceci sera abordé
dans un prochain chapitre.)
|
 |
 |
 |
Each of these has an
associated subclass of InputStream. In addition, the
FilterInputStream is also a type of InputStream, to provide a base
class for "decorator" classes that attach attributes or useful interfaces to
input streams. This is discussed later.
|
 |
Chacun d'entre eux possède une sous-classe associée
d'InputStream. En plus, le FilterInputStream est aussi un type
d'InputStream, fournissant une classe de base pour les classes de
« décoration » lesquelles attachent des attributs ou des interfaces utiles aux flux
d'entrée. Ceci est abordé plus tard.
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |