« Nous allons commencer par les flux pour l'entrée/la sortie de fichiers. Mais prenons les choses par le bon bout. »

Il y a deux classes pour lire et écrire des fichiers : FileInputStream et FileOutputStream. Comme tu l'auras probablement déjà deviné, FileInputStream peut lire de manière séquentielle les octets d'un fichier, et FileOutputStream écrire de manière séquentielle des octets dans un fichier. Voici les méthodes que ces classes possèdent :

Méthode Ce que la méthode fait
FileInputStream(String fileName);
- Il s'agit du constructeur. Il te permet de spécifier le nom d'un fichier sur le disque, à partir duquel l'objet créé lira les données.
int read();
- Cette méthode lit un octet depuis le fichier et le renvoie. La valeur de retour est élargie en int.
int available();
- Cette méthode renvoie le nombre d'octets non lus (disponibles).
void close();
- Cette méthode « ferme » le flux. Tu peux l'appeler quand tu as fini de travailler avec le flux.
L'objet effectue alors les opérations d'entretien nécessaires pour fermer le fichier, etc.
À ce stade, tu ne peux plus lire de données à partir du flux.

Juste pour le plaisir, nous allons calculer la somme de tous les octets dans un fichier. Voici à quoi le code ressemble :

Somme de tous les octets dans un fichier
public static void main(String[] args) throws Exception
{
 //Créer un objet FileInputStream lié à « c:/data.txt ».
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 long sum = 0;

 while (inputStream.available() > 0) //tant qu'il reste des octets non lus
 {
  int data = inputStream.read(); //Lit l'octet suivant
  sum +=  data; //L'ajoute au total actuel
 }
 inputStream.close(); // Ferme le flux

 System.out.println(sum); // Affiche la somme à l'écran.
}

« Nous avons déjà étudié quelque chose de semblable. Comment est-ce que la classe FileOutputStream est organisée ? »

« Très bien. Regarde ça : »

Méthode Ce que la méthode fait
FileOutputStream (String fileName);
« Il s'agit du constructeur. Il te permet de spécifier le nom d'un fichier sur le disque, dans lequel l'objet écrira les données. »
void write(int data);
« Cette méthode écrit l'octet suivant, en tronquant les données à un octet. »
void flush();
« Les données à écrire sont souvent d'abord recueillies dans de grands blocs en mémoire, et seulement alors écrites sur le disque. »

La commande flush force l'écriture de toutes les informations non enregistrées sur le disque.

void close();
« Cette méthode 'ferme' le flux. Tu peux l'appeler quand tu as fini de travailler avec le flux. »
L'objet effectue alors les opérations d'entretien nécessaires pour fermer le fichier, etc.

Tu ne peux plus écrire des données sur le flux, et la méthode flush est appelée automatiquement.

« C'est tout ? »

« Oui, il n'existe en fait qu'une seule méthode pour l'écriture : write(). Et elle écrit un seul octet à la fois. Mais elle te permet d'écrire autant d'informations que tu veux dans le fichier. »

La programmation est le processus de division d'une tâche vaste et complexe en de nombreux petits éléments. C'est essentiellement le même processus qui se déroule ici : la lecture/écriture de gros blocs de données est divisée en lecture/écriture de petits morceaux d'un octet à la fois.

Voici comment tu peux utiliser ces classes pour copier un fichier sur le disque :

Copier un fichier sur le disque
public static void main(String[] args) throws Exception
{
 //Créer un flux pour lire des octets depuis un fichier
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 //Créer un flux pour écrire des octets dans un fichier
 FileOutputStream outputStream = new FileOutputStream("c:/result.txt");

 while (inputStream.available() > 0) //tant qu'il reste des octets non lus
 {
  int data = inputStream.read(); // Lit l'octet suivant dans la variable data
  outputStream.write(data); // et l'écrit dans le second flux
 }

 inputStream.close(); //Ferme les deux flux. Nous n'en avons plus besoin.
 outputStream.close();
}

« Merci, Rishi. Je comprends enfin comment ce code fonctionne réellement. »