Flux de Caractères
Les flux de Caractères traitent les données unité par unité en caractères, permettant uniquement la lecture de fichiers texte. Ils convertissent les octets lus en caractères à l'aide d'une table d'encodage. Les classes abstraites Reader et Writer servent de base, tandis que InputStreamReader et OutputStreamWriter sont des flux de conversion qui héritent de ces dernières pour effectuer la transformation des octets en caractères.
1. FileReader et FileWriter pour la lecture/écriture de fichiers
| Méthodes courantes de FileReader | Description |
|---|---|
| FileReader(String nomFichier) | Constructeur spécifiant le fichier à lire |
| int read() | Lit un caractère, retourne sa valeur de code ou -1 si fin de flux |
| int read(char[] tableau) | Lit un tableau de caractères, retourne le nombre effectif de caractères lus |
| Méthodes courantes de FileWriter | Description |
|---|---|
| FileWriter(String nomFichier, boolean ajout) | Constructeur pour le fichier à écrire, avec option d'ajout ou d'écrasement |
| void write(int c) | Écrit un caractère |
| void write(char[] tableau, int offset, int longueur) | Écrit une portion d'un tableau de caractères |
1.1 Lecture caractère par caractère
public class LectureSimple {
public static void main(String[] args) throws IOException {
FileReader lecteur = new FileReader("donnees.txt");
FileWriter redacteur = new FileWriter("sortie.txt");
int symbole;
while ((symbole = lecteur.read()) != -1) {
redacteur.write(symbole);
}
lecteur.close();
redacteur.close();
}
}
1.2 Lecture par tableau de caractères
public class LectureTableau {
public static void main(String[] args) throws IOException {
FileReader source = new FileReader("donnees.txt");
FileWriter destination = new FileWriter("sortie.txt");
int quantiteLue;
char[] tampon = new char[1024];
while ((quantiteLue = source.read(tampon)) != -1) {
destination.write(tampon, 0, quantiteLue);
}
source.close();
destination.close();
}
}
2. Flux tamponnés pour caractères (flux d'emballage)
| Méthodes courantes de BufferedReader | Description |
|---|---|
| BufferedReader(Reader entree) | Constructeur prenant un objet Reader |
| String readLine() | Lit une ligne complète |
| Méthodes courantes de BufferedWriter | Description |
|---|---|
| BufferedWriter(Writer sortie) | Constructeur prenant un objet Writer |
| void write(String chaine) | Écrit une chaîne de caractères |
| void newLine() | Écrit un saut de ligne |
2.1 Utilisation de BufferedReader et BufferedWriter
Ces flux d'emballage enveloppent les flux de nœuds FileReader et FileWriter pour améliorer l'efficacité via la lecture/écriture ligne par ligne. Le constructeur de FileWriter avec un booléen permet l'ajout au contenu existant sans écrasement. La méthode newLine() insère un saut de ligne dans le fichier.
public class TraitementLignes {
public static void main(String[] args) throws IOException {
FileReader lecteurBrut = new FileReader("entree.txt");
FileWriter redacteurBrut = new FileWriter("sortie.txt", true);
BufferedReader lecteurTampon = new BufferedReader(lecteurBrut);
BufferedWriter redacteurTampon = new BufferedWriter(redacteurBrut);
String ligne;
while ((ligne = lecteurTampon.readLine()) != null) {
redacteurTampon.write(ligne);
redacteurTampon.newLine();
}
lecteurTampon.close();
redacteurTampon.close();
}
}
2.2 Lecture depuis la console avec BufferedReader
public class LectureConsole {
public static void main(String[] args) throws IOException {
BufferedReader entreeConsole = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Entrez une chaîne :");
String saisie = entreeConsole.readLine();
System.out.println("Saisie : " + saisie);
}
}
Flux d'Octets pour Entrée/Sortie d'Objets
ObjectInputStream permet de lire des objets depuis un fichier, tandis qu'ObjectOutputStream les y écrit. Ces flux d'emballage s'appliquent aux flux do'ctets pour la sérialisation.
1. Besoin de la sérialisation d'objets
Les objets créés en mémoire sont éphémères et détruits à la fin du programme. La sérialisation persiste leurs données dans un fichier, permettant leur restauration ultérieure, comme pour sauvegarder les données d'utilisateurs lors de maintenances de serveurs.
2. Sérialisation et désérialisation d'objets
Sérialisation : Écriture des informations d'un objet dans un fichier via ObjectOutputStream.
| Méthodes courantes de ObjectOutputStream | Description |
|---|---|
| ObjectOutputStream(OutputStream sortie) | Constructeur prenant un flux de sortie |
| writeObject(Object objet) | Écrit un objet dans le fichier |
Désérialisation : Lecture d'un objet depuis un fichier via ObjectInputStream.
| Méthodes courantes de ObjectInputStream | Description |
|---|---|
| ObjectInputStream(InputStream entree) | Constructeur prenant un flux d'entrée |
| Object readObject() | Lit et retorune un objet depuis le fichier |
Pour sérialiser une classe personnalisée, elle doit implémenter l'interface Serializable, qui génère automatiquement un numéro de sérialisation unique. Ce numéro idnetifie la classe ; si la classe est modifiée, un nouveau numéro est généré, ce qui peut causer des erreurs lors de la désérialisation d'anciennes instances.
import java.io.Serializable;
public class Etudiant implements Serializable {
private static final long serialVersionUID = 123456789L;
private int code;
private String nom;
public Etudiant(int code, String nom) {
this.code = code;
this.nom = nom;
}
// Getters et setters omis pour concision
@Override
public String toString() {
return "Etudiant{code=" + code + ", nom='" + nom + "'}";
}
}
public class SerialisationDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Etudiant eleve = new Etudiant(101, "Alice");
// Sérialisation
FileOutputStream fluxSortie = new FileOutputStream("etudiant.bin");
ObjectOutputStream sortieObjet = new ObjectOutputStream(fluxSortie);
sortieObjet.writeObject(eleve);
sortieObjet.close();
// Désérialisation
FileInputStream fluxEntree = new FileInputStream("etudiant.bin");
ObjectInputStream entreeObjet = new ObjectInputStream(fluxEntree);
Etudiant restaure = (Etudiant) entreeObjet.readObject();
System.out.println(restaure);
entreeObjet.close();
}
}
Pour éviter les erreurs dues aux modifications de classe, déclarez explicitement un serialVersionUID. Ainsi, le numéro reste constant malgré les changements dans la structure de la classe. Notez que si la classe est modifiée, une nouvelle sérialisation est nécessaire pour refléter les modifications.
3. Configuration d'IDEA pour le serialVersionUID
Dans les versions récentes d'IDEA, configurez les paramètres pour générer automatiquement un serialVersionUID lorsque l'interface Serializable est implémentée. Placez le curseur sur le nom de classe pour afficher l'option. Cela garantit la compatibilité lors des sérialisations ultérieures, sous réserve de re-sérialiser les objets après des modifications de classe.