« Bonjour, Amigo ! Je vais maintenant te parler de deux interfaces : InputStream et OutputStream. Elles sont déclarées comme des classes abstraites, mais si tu regardes de plus près, tu verras que ce sont essentiellement des interfaces. Presque toutes leurs méthodes sont abstraites, à l'exception de quelques méthodes peu importantes. Elles sont très semblables au 'garde du corps' que nous avons considéré plus tôt. »

Ce sont des interfaces très intéressantes. Pour l'instant, je vais délibérément les appeler interfaces, pour que tu puisses comprendre pourquoi nous en avons besoin. Et ensuite nous verrons pourquoi ce sont en fait des classes abstraites.

« OK. Alors que sont ces interfaces ? »

« Je vais te le dire sans plus tarder. »

Java a cette chose intéressante qu'on appelle « flux ». Un flux est une entité très simple. Et sa simplicité est la clé qui donne accès à un moyen très puissant d'échanger des données. Il existe deux types de flux : des flux pour la lecture et des flux pour l'écriture.

Comme tu l'as probablement déjà deviné, tu peux écrire des données dans un flux d'écriture. Il a une méthode write pour cela. Tu peux lire des données à partir d'un flux de lecture. Il a une méthode read() pour cela.

InputStream est l'interface pour un flux qui prend en charge la lecture. Elle définit la capacité suivante : 'les octets qui peuvent être lus à partir de moi'.

De même, OutputStream est une interface pour un flux qui prend en charge l'écriture. Elle définit la capacité suivante : 'les octets qui peuvent être écrits sur moi'.

« C'est tout ? »

« À peu près. Mais l'important est que Java a des tonnes de classes qui peuvent travailler avec InputStream et OutputStream. Par exemple, supposons que tu veux lire un fichier à partir du disque et afficher son contenu à l'écran. Rien de plus simple. »

Pour lire des données à partir d'un fichier sur le disque, nous avons la classe spéciale FileInputStream, qui implémente l'interface InputStream. Tu veux écrire ces données dans un autre fichier ? Pour cela, nous avons la classe FileOutputStream, qui implémente l'interface OutputStream. Le code suivant montre ce que tu dois faire pour copier des données d'un fichier à un autre.

Code
public static void main(String[] args) throws IOException
{
 InputStream inStream = new FileInputStream("c:/source.txt");
 OutputStream outStream = new FileOutputStream("c:/result.txt");

 while (inStream.available() > 0)
 {
  int data = inStream.read(); //read one byte from the input stream
  outStream.write(data); //write that byte to the other stream.
 }

 inStream.close(); //close the streams
 outStream.close();
}

Imagine que nous avons écrit une classe et que nous lui avons ajouté les capacités  InputStream  et  OutputStream.

Si nous avons bien implémenté ces interfaces, alors les instances de notre classe peuvent maintenant être enregistrées ou lues à partir d'un fichier. On peut simplement lire leur contenu en utilisant la méthode read. Ou on peut les charger à partir d'un fichier en créant un objet et en utilisant la méthode write pour écrire le contenu du fichier.

« Un exemple, peut-être ? »

« Très bien. »

Code Description
class MyClass
{
private ArrayList<Integer> list;
}
Par souci de simplicité, imagine que notre classe contient un objet, une ArrayList qui contient des objets Integer.

Maintenant, nous allons lui ajouter des méthodes de lecture et d'écriture

Code Description
class MyClass
{
private ArrayList<Integer> list;
public void write(int data)
{
list.add(data);
}
public int read()
{
int first = list.get(0);
list.remove(0);
return first;
}

public int available()
{
return list.size();
}
}
Maintenant, notre classe implémente la méthode read, qui permet de lire séquentiellement la totalité du contenu de la liste.

Et la méthode write qui te permet d'écrire des valeurs dans notre liste.

Bien sûr, ce n'est pas une implémentation des interfaces InputStream et OutputStream, mais c'est très similaire.

« Oui, je comprends. Alors comment enregistres-tu le contenu d'un tel objet dans un fichier ? »

« Je vais prendre un exemple : »

Écriture d'un objet MyClass dans un fichier
public static void main(String[] args)
{
 MyClass myObject = new MyClass();
 OutputStream outStream = new FileOutputStream ("c:/my-object-data.txt");

 while (myObject.available() > 0)
 {
  int data = myObject.read(); //read one int from the input stream
  outStream.write(data); //write that int to the other stream.
 }

 outStream.close();
}
Lit un objet MyClass à partir d'un fichier
public static void main(String[] args)
{
 InputStream inStream = new FileInputStream("c:/my-object-data.txt");
 MyClass myObject = new MyClass();

 while (inStream.available() > 0)
 {
  int data = inStream.read(); //read one int from the input stream
  myObject.write(data); //write that int to the other stream.
 }

 inStream.close(); //close the streams
}

« Nom d'une pipe en bois ! C'est vraiment très semblable au travail avec InputStream/OutputStream. J'adore les flux ! »

« Tu l'as dit ! »