ENPC - Programmation - Corrections 10

Exercice 1: chaînes de caractères dans un fichier.

Afin de pouvoir relire individuellement les chaînes sauvegardées, il est nécessaire de les séparer les unes des autres par un ou des caractères spéciaux (un séparateur). Pour faire simple, on peut utiliser ici le caractère de fin de ligne (ou retour chariot).

import java.io.*;
import java.util.*;

public class Exercice1 {
    /**
     * Écrit dans le fichier de nom fileName les chaînes 
     * de caractères contenues dans le tableau t, stockées 
     * une par ligne.
     */
    public static void ecrire(String fileName, String[] t) 
	throws IOException {
	// Création d'un objet "contrôleur de fichier"
	File f = new File(fileName);
	// Création d'un flot d'écriture de caractères sur ce fichier
	FileWriter fw = new FileWriter(f);
	// Décoration de ce flot pour écrire des "fins de ligne".
	PrintWriter pw = new PrintWriter(fw);
	
	for(int i=0; i<t.length; i++){
	    pw.print(t[i]);
	    pw.println();
	    // les deux peuvent se faire par pw.println(t[i])
	}
	// Fermeture du flot
	pw.close();
    }

    /**
     * Lit depuis le fichier de nom fileName les chaînes 
     * de caractères, une par ligne, et les retourne dans 
     * un tableau de String.
     */
    public static String[] lire(String fileName) 
	throws IOException {
	// Création d'un objet "contrôleur de fichier"
	File f = new File(fileName);
	// Création d'un flot de lecture de caractères sur ce fichier
	FileReader fr = new FileReader(f);
	// Décoration de ce flot pour lire "par ligne".
	BufferedReader br = new BufferedReader(fr);
	
	// On doit utiliser une structure intermédiaire 
	// pour savoir combien il y a de chaînes
	ArrayList l = new ArrayList();
	
	String s = br.readLine();
	for(; s!=null; ){
	    l.add(s);
	    s = br.readLine();
	}
 	// Fermeture du flot
	br.close();
	String[] t = new String[0];
	return (String[]) l.toArray(t);
    }

    /**
     * Méthode de test
     */
    public static void main(String[] args) throws IOException {
	String fileName = "toto";
	Exercice1.ecrire(fileName, args);
	String[] t = Exercice1.lire(fileName);
	for(int i=0;i<t.length;i++) {
	    System.out.println(t[i]);
	}
    }
}

Exercice 2: mise en majuscule.

import java.io.*;

public class Exercice2 {
    final static String FIN = ".";
    public static void main(String[] args) throws IOException {
	// Flot d'entrée
	BufferedReader br = 
	    new BufferedReader(new InputStreamReader(System.in));
	String s;
	while ((s = br.readLine())!= null) {
	    if (s.equals(Exercice2.FIN))
		break;
	    System.out.println(s.toUpperCase());
	}
	br.close();
    }
}

Exercice 3: enregistrement et lecture d'objet.

import java.io.*;

public class Exercice3 {
    public static void main(String[] args) 
	throws IOException, ClassNotFoundException {
	String fileName = "toto";
	ObjectOutputStream oos = 
	    new ObjectOutputStream(new FileOutputStream(fileName));
	oos.writeObject(args);
	oos.close();
	
	ObjectInputStream ois = 
	    new ObjectInputStream(new FileInputStream(fileName));
	Object o = ois.readObject();
	ois.close();
	
	// Transtypage nécessaire
	String[] t = (String[]) o;
	for(int i=0; i<t.length; i++) {
	    System.out.println(t[i]);
	}
    }
}

Exercice 4: sérialisation de la classe Point.

Si on a la classe Point suivante:

public class Point {
    double x;
    double y;
    public Point() {}
    public Point(double x, double y) {
	this.x = x;
	this.y = y;
    }
    public String toString() {
	return "("+x+","+y+")";
    }
    public void translate(double dx, double dy) {
	x+=dx;
	y+=dy;
    }
}

Et qu'on écrit la classe suivante pour sérialiser puis désérialiser une liste d'instances de la classe Point:

import java.io.*;
import java.util.*;

public class Exercice4 {
    public static void main(String[] args) 
	throws IOException, ClassNotFoundException {
	String fileName = "toto";
	ObjectOutputStream oos = 
	    new ObjectOutputStream(new FileOutputStream(fileName));

        // création de la liste à sérialiser
	List liste = new LinkedList();
	Point p1 = new Point();
	liste.add(p1);
	Point p2 = new Point(1,1);
	liste.add(p2);
	Point p3 = new Point(1,2);
	liste.add(p3);

        // sérialisation
	oos.writeObject(liste);
	oos.close();
	
	ObjectInputStream ois = 
	    new ObjectInputStream(new FileInputStream(fileName));

        // désérialisation
	Object o = ois.readObject();
	ois.close();

	// Transtypage nécessaire
	List l = (List) o;
	for(Iterator it = l.iterator(); it.hasNext(); ) {
	    Point p = (Point) it.next();
	    p.translate(5,5);
	    System.out.println(p);
	}
    }
}

L'exécution du programme ci-dessus lève une exception du type NotSerializableException. En effet, la classe Point n'implante pas l'interface Serializable, et pour que le programme s'exécute correctement, il faut simplement ajouter ceci au début de la classe Point:

import java.io.*;
public class Point implements Serializable {
  ...
}

Etienne.Duris[at]univ-mlv.fr - © École Nationale des Ponts et Chaussées - Janvier 2002 - http://www-igm.univ-mlv.fr/~duris/ENPC/