Comprendre les flux d'entrées/sorties en Java
Tags: java, file, input, output
Published: 2023-03-31 17:04:34

Les flux d'entrées/sorties (E/S) sont un aspect fondamental de la programmation qui permet aux programmes d'interagir avec leur environnement. Les entrées/sorties peuvent prendre plusieurs formes, notamment la lecture et l'écriture de fichiers, les flux d'entrées/sorties et les sérialisations. Dans cet article, nous examinerons chacune de ces formes d'E/S en détail, en illustrant leur utilisation avec des exemples simples en Java.

### La lecture et l'écriture de fichiers

La lecture et l'écriture de fichiers sont des formes courantes d'E/S en programmation. La **lecture** de fichiers permet aux programmes de **récupérer des données à partir de fichiers**, tandis que l'**écriture** de fichiers permet aux programmes de **stocker des données dans des fichiers**.

En Java, la lecture et l'écriture de fichiers sont gérées à l'aide de la classe File. La **classe File** permet de créer, lire, écrire et supprimer des fichiers. Voici un exemple simple de création d'un fichier en Java :
```Java
File file = new File("monfichier.txt");
file.createNewFile();
```
Dans cet exemple, nous créons un nouveau fichier appelé "**monfichier.txt**" en utilisant la méthode **createNewFile()** de la classe **File**. Cette méthode crée un nouveau fichier vide dans le répertoire actuel.

Pour lire le contenu d'un fichier, nous pouvons utiliser la **classe Scanner** de Java. Voici un exemple de lecture d'un fichier en Java :
```Java
File file = new File("monfichier.txt");
Scanner scanner = new Scanner(file);

while (scanner.hasNextLine()) {
    String line = scanner.nextLine();
    System.out.println(line);
}

scanner.close();
```
Dans cet exemple, nous créons un nouvel objet **Scanner** en utilisant le fichier "**monfichier.txt**" que nous avons créé précédemment. Nous utilisons ensuite une boucle **while** pour **lire chaque ligne** du fichier à l'aide de la méthode **nextLine()** de la classe Scanner. Enfin, nous fermons l'objet Scanner en utilisant la méthode **close()**.

Pour **écrire dans un fichier**, nous pouvons utiliser la classe **FileWriter**. Voici un exemple d'écriture dans un fichier en Java :
```Java
File file = new File("monfichier.txt");
FileWriter writer = new FileWriter(file);

writer.write("Ceci est une ligne de texte");
writer.close();
```
Dans cet exemple, nous créons un nouvel objet **FileWriter** en utilisant le fichier "**monfichier.txt**" que nous avons créé précédemment. Nous utilisons ensuite la méthode **write()** de la classe **FileWriter** pour écrire une ligne de texte dans le fichier. Enfin, nous fermons l'objet FileWriter en utilisant la méthode **close()_**.

_**NB**: Il est important de **fermer les objets d'E/S** pour **libérer les ressources**, **finaliser les opérations** et **éviter les fuites de mémoire**. Il est donc recommandé de toujours fermer correctement les objets d'E/S après leur utilisation, en utilisant la méthode **close()**.__

### Les flux d'entrées/sorties

Les flux d'entrées/sorties sont un autre aspect important des E/S en programmation. Les **flux d'entrées/sorties** permettent aux programmes de **lire et d'écrire des données en temps réel, sans avoir à stocker les données dans des fichiers**.

En Java, les flux d'entrées/sorties sont gérés à l'aide des classes **InputStream** et **OutputStream**. Voici un exemple simple d'utilisation de ces classes en Java :
```Java
InputStream input = System.in;
OutputStream output = System.out
```
Dans cet exemple, nous créons un objet **InputStream** appelé **input** en utilisant la méthode **System.in**, qui permet de **lire les données d'entrée** standard de l'utilisateur (généralement le **clavier**). Nous créons également un objet **OutputStream** appelé **output** en utilisant la méthode **System.out**, qui permet d'**écrire les données de sortie** standard (généralement l'écran).

Nous pouvons utiliser ces objets pour **lire et écrire des données en temps réel**. Par exemple, voici un exemple de programme Java qui demande à l'utilisateur de saisir son nom et qui affiche un message de bienvenue :
```Java
InputStream input = System.in;
OutputStream output = System.out;
Scanner scanner = new Scanner(input);

output.write("Entrez votre nom : ".getBytes());
String nom = scanner.nextLine();

output.write(("Bienvenue, " + nom + "!").getBytes());

scanner.close();
```
Dans cet exemple, nous utilisons un objet **Scanner** pour **lire** l'entrée de l'utilisateur à l'aide de la méthode **nextLine()**. Nous utilisons également la méthode **getBytes()** de la classe **String** pour convertir notre chaîne de caractères en **tableau de bytes** avant de l'écrire dans le flux de sortie à l'aide de la méthode **write()** de la classe **OutputStream**.

### Les sérialisations

Les **sérialisations** sont une autre forme d'E/S en programmation qui permet de **convertir des objets Java en une représentation binaire**, qui peut être **stockée** ou **transmise** via un réseau, et de les reconvertir en objets Java.

En Java, la sérialisation est gérée à l'aide de l'interface **Serializable**. Pour qu'un objet Java soit sérialisable, il doit implémenter cette interface. Voici un exemple simple de sérialisation d'un objet en Java :
```Java
public class Personne implements Serializable {
    private String nom;
    private int age;

    public Personne(String nom, int age) {
        this.nom = nom;
        this.age = age;
    }

    public String getNom() {
        return nom;
    }

    public int getAge() {
        return age;
    }
}
```
Dans cet exemple, nous avons créé une classe **Personne** qui implémente **l'interface Serializable**. Cette classe a deux propriétés : nom et age, ainsi que deux méthodes d'accès pour ces propriétés.

Pour sérialiser un objet **Personne**, nous pouvons utiliser la classe **ObjectOutputStream**. Voici un exemple simple :
```Java
Personne p = new Personne("Alice", 25);
File file = new File("personne.ser");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(p);

oos.close();
```
Dans cet exemple, nous avons créé un objet **Personne** appelé **p**. Nous avons ensuite créé un **fichier** appelé "**personne.ser**" et ouvert un flux de sortie vers ce fichier à l'aide de la classe **FileOutputStream**. Nous avons ensuite créé un objet **ObjectOutputStream** en utilisant ce flux de sortie.

Enfin, nous avons utilisé la méthode **writeObject()** de la classe **ObjectOutputStream** pour sérialiser l'objet **p** dans le fichier. Nous avons ensuite **fermé** l'objet **ObjectOutputStream** en utilisant la méthode **close()**.

Pour **désérialiser** un objet **Personne**, nous pouvons utiliser la classe **ObjectInputStream**. Voici un exemple simple :
```Java
File file = new File("personne.ser");
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);

Personne p = (Personne) ois.readObject();

ois.close();
```
Dans cet exemple, nous avons créé un objet **File** pour le fichier "**personne.ser**" que nous avons précédemment créé. Nous avons ensuite ouvert un **flux d'entrée** vers ce fichier à l'aide de la classe **FileInputStream**, puis créé un objet **ObjectInputStream** en utilisant ce flux d'entrée.

Enfin, nous avons utilisé la méthode **readObject()** de la classe **ObjectInputStream** pour désérialiser l'objet **Personne** contenu dans le fichier. Nous avons ensuite fermé l'objet **ObjectInputStream** en utilisant la méthode **close()**.

### Conclusion

En résumé, les **entrées/sorties** en Java sont essentielles pour la **manipulation de fichiers** et la **communication** avec l'utilisateur. Les flux d'entrées/sorties permettent de **lire** et d'**écrire** des données en temps réel, tandis que les sérialisations permettent de convertir des objets Java en une représentation binaire pour le stockage ou la transmission. En maîtrisant ces concepts, les développeurs Java peuvent écrire des programmes plus robustes et plus interactifs.