t
t
t
t
t t   11) Le système d’E/S de Java
tttt
t
carrea) Préface carreb) Avant-propos carre1) Introduction sur les &laqo; objets » carre2) Tout est &laqo; objet » carre3) Contrôle du flux du programme carre4) Initialization & Cleanup carre5) Cacher l'implémentation carre6) Réutiliser les classes carre7) Polymorphisme carre8) Interfaces & classes internes carre9) Stockage des objets carre10) Error Handling with Exceptions 11) Le système d’E/S de Java carre12) Identification dynamique de type carre13) Création de fenêtres & d'Applets carre14) Les &laqo; Threads » multiples carre15) Informatique distribuée carreA) Passage et retour d'objets carreB) L'Interface Java Natif (JNI) carreC) Conseils pour une programation stylée en Java carreD) Resources
Texte original t Traducteur : Armel Fortun
t
t
    
Ce chapitre contient 10 pages
1 2 3 4 5 6 7 8 9 10
\\\
t t t
t t t
t
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
t t t
11: The Java
I/O System
t 11: Le système d'E/S de Java
t t t
Creating a good input/output (I/O) system is one of the more difficult tasks for the language designer.
t 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.
t t t
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.).
t 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.).
t t t
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.
t 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.
t t t
This chapter will give you an introduction to the variety of I/O classes in the standard Java library and how to use them.
t 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.
t t t

The File class

t

La classe File

t t t
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.
t 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.
t t t
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.
t 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.
t t t

A directory lister

t

Lister un répertoire

t t t
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.
t 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.
t t t
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:
t 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 :
t t t
//: 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; } } ///:~ t
//: 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;
}
} ///:~
t t t
The DirFilter class “implements” the interface FilenameFilter. It’s useful to see how simple the FilenameFilter interface is:
t La classe DirFilter « implémente » l'interface FilenameFilter. Il est utile de voir combien est simple l'interface FilenameFilter :
t t t
public interface FilenameFilter { boolean accept(File dir, String name); } t
public interface FilenameFilter {
boolean accept(File dir, String name);
}
t t t
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.
t 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.
t t t
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.
t 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éé.
t t t
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( ).
t 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().
t t t
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.
t 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.
t t t
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++.
t 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++.
t t t

Anonymous inner classes

t

Les classes internes anonymes

t t t
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:
t 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 :
t t t
//: 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]); } } ///:~ t
//: 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]);
}
} ///:~
t t t
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.
t 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.
t t t
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:
t 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 :
t t t
//: 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]); } } ///:~ t
//: 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]);
}
} ///:~
t t t
The argument to main( ) is now final, since the anonymous inner class uses args[0] directly.
t L'argument de main() est maintenant final, puisque la classe anonyme interne utilise directement args[0].
t t t
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.
t 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.
t t t

Checking for and creating directories

t

Vérification et création de répertoires

t t t
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):
t 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) :
t t t
//: 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); } } } ///:~ t
//: 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);
}  
}
} ///:~
t t t
In fileData( ) you can see various file investigation methods used to display information about the file or directory path.
t 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.
t t t
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.
t 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.
t t t
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.
t 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.
t t t

Input and output

t

Entrée et sortie

t t t
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.
t 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.
t t t
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.
t 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.
t t t
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.
t 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.
t t t

Types of InputStream

t

Les types d'InputStream

t t t
InputStream’s job is to represent classes that produce input from different sources. These sources can be:
t Le boulot d'InputStream est de représenter les classes qui produisent l'entrée depuis différentes sources. Ces sources peuvent êtres :
t t t
  1. An array of bytes.
  2. A String object.
  3. A file.
  4. A “pipe,” which works like a physical pipe: you put things in one end and they come out the other.
  5. A sequence of other streams, so you can collect them together into a single stream.
  6. Other sources, such as an Internet connection. (This will be discussed in a later chapter.)
t
  1. Une série de bytes.
  2. Un objet String.
  3. Un fichier.
  4. Un « tuyau », lequel fonctionne comme un vrai tuyau : vous introduisez des choses à une entrée et elles ressortent de l'autre.
  5. Une succession d'autres flux, que vous pouvez ainsi rassembler dans un seul flux.
  6. D'autres sources, comme une connexion internet. (Ceci sera abordé dans un prochain chapitre.)
t t t
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.
t 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.
t t t
t t t
t t
    
///
t t t
t
     
Sommaire Le site de Bruce Eckel