C. RECANATI

IHM Java

Master M1 2005

 

 

 

 

 

 

TP n¡ 4-5

 

 

Exercice 1: Sorties mises en tampon (= « bufferisées ») vers un fichier.

1) Ecrire un programme qui calcule les 200 premiers nombres premiers et les stocke dans un tableau, considéré ici comme tampon (ou, pour utiliser le terme anglais, considéré ici comme buffer).

2) Ecrire ensuite les nombres trouvés dans le fichier intitulé « premiers.bin » d’un répertoire « DonnesUtilisables », en faisant les tests nécessaires pour vérifier que « DonnesUtilisables » correspond bien à un nom de répertoire (et créer ce répertoire s’il n’existe pas).

3) Créer un flot de sortie des données du tableau tampon vers le fichier « premiers.bin », et écrire les nombres premiers (du tableau) dans ce fichier à l’aide de la méthode writeLong().  Fermer ensuite le flot et en imprimer la taille. Le résultat obtenu vous semble-t-il raisonnable ? (rappel : vous devez avoir écrit 200 valeurs de type long de 8 octets chacune).

 

Exercice 2 : (variante, si vous en avez le temps ou l’envie …)

A partir de l’exercice précédent, écrire un fichier compressé (format ZIP) dans le même répertoire, contenant les mêmes sorties (nombres premiers) compressées.

F  on crée un flot de sortie Zip (ZipOutputStream  au lieu de créer un dataOutputStream) ;  on crée une entrée zip pour le fichier (objet de type ZipEntry) et on écrit dans le flot de sortie zip avec la méthode putNextEntry(). On a donc le bout de code suivant :

         ZipEntry monEntreeZip = new ZipEntry(nomFichier) ;

         monFichierZip.putNextEntry(monEntreeZip) ;

Créer ensuite le flot de sortie vers le flot de sortie zip et écrire le tableau d’entiers dedans.

 

 

 

Eléments de correction

Exercice 1:

import java.io.* ;

import java.util.zip.* ;

 

public class TestDeSortieDeNombresPremiers {

            public static void main (String [ ] args ) {

                        long [ ] premiers = new long[200] ;

                        premiers[0] = 2 ;

                        premiers[1] = 3 ;

                        int compteur = 2 ;        // nb premiers trouvés jusqu’à présent

 

                        long nombre = 5 ; // l’entier suivant à tester

exterieur :                    for ( ; compteur < premiers.length ; nombre += 2L) {

                                   // le div. max à tester est la racine carrée du nombre

                                   long limite = (long)Math.ceil

                                                                       (Math.sqrt((double) nombre)) ;

                                   for (int i=1 ; i<count && premiers[i] <= limite ; i++)

                                               if (nombre%premiers[i] == 0) // diviseur ?

                                                           continue exterieur ; // oui, essayer suivant

                                   premiers [compteur++] = nombre ; // en voilà un !

                        }

                        // écrire les nombres premiers dans un fichier

                        try {

                           String nomDuRepertoire = « ../DonneesUtilisables » ;

                           String nomFichier = « premiers.bin » ; // nom du fichier

 

                           File monRepNbPremiers = new File (nomDuRepertoire) ;

                           if ( !monRepNbPremiers.exists()) // s’il le rep n’existe pas

                                   monRepNbPremiers.mkdir() ; // le créer

                           else

                                   if ( !monRepNbPremiers.isDirectory()) {

                                               System.out.println(nomDuRepertoire +

                                                                                   « n’est pas un répertoire ») ;

                                               return ;

                                   }

                           // créer l’objet File

                           File fichierNbPremiers = new File (monRepNbPremiers,

                                                                                               nomFichier) ;

                           fichierNbPremiers.createNewFile() ; // s’il n’existe pas, le créer

 

                           // créer un flot de sortie des données mis en tampon pour

                           // le fichier

                           DataOutputStream premiersStream

                                               = new DataOutputStream (

                                                           new BufferedOutputStream (

                                                           new FileOutputStream

                                                                                   (fichierNbPremiers))) ;

 

                           // écrire les nb premiers dans le fichier

                           for (int i=0 ; i<premiers.length ; i++)

                                   premiersStream.writeLong(premiers[i]) ;

 

                           premiersStream.close() ;// vider et fermer le fichier

                           System.out.println(« Taille du fichier = »

                                                                       + premiersStream.size()) ;

                        }

                        catch (IOException e)

                                   System.out.println(« IOException  » + e

                                                                                   + «  est survenue ») ;

            }

}

Exercice 2:

import java.io.* ;

import java.util.zip.* ;

 

public class TestDeSortieDeNombresPremiersZip {

            public static void main (String [ ] args ) {

                        long [ ] premiers = new long[200] ;

                        premiers[0] = 2 ;

                        premiers[1] = 3 ;

                        int compteur = 2 ;        // nb premiers trouvés jusqu’à présent

 

                        long nombre = 5 ; // l’entier suivant à tester

exterieur :        for ( ; compteur < premiers.length ; nombre += 2L) {

                                   long limite = (long)Math.ceil

                                                                       (Math.sqrt((double) nombre)) ;

                                   for (int i=1 ; i<count && premiers[i] <= limite ; i++)

                                               if (nombre%premiers[i] == 0) // diviseur ?

                                                           continue exterieur ; // oui, essayer suivant

                                   premiers [compteur++] = nombre ; // en voilà un !

                        }

 

                        try {

                           String nomDuRepertoire = « ../DonneesInutilisables » ;

                           String nomDuZip = « premiers.zip » ; // l’archive

                           String nomFichier = « premiers.bin » ; // fichier compressé

 

                           File monRepNbPremiers = new File (nomDuRepertoire) ;

                           if ( !monRepNbPremiers.exists())

                                   monRepNbPremiers.mkdir() ;

                           else

                                   if ( !monRepNbPremiers.isDirectory()) {

                                               System.out.println(nomDuRepertoire

                                                                                   + « n’est pas un répertoire ») ;

                                               return ;

                                   }

                           // créer l’objet File

                           File monZipNbPremiers = new File (monRepNbPremiers,

                                                                                               nomDuZip) ;

                           monZipNbPremiers.createNewFile() ; // s’il n’existe pas, le créer

 

                           // créer le flot de sortie zip

                           ZipOutputStream monFichierZip

                                               = new ZipOutputStream (

                                                                       new FileOutputStream (

                                                                                   monZipNbPremiers))) ;

 

                           // créer l’entrée zip pour le fichier et l’écrire dans le flot

                           // de sortie zip

                           ZipEntry monEntreeZip = new ZipEntry (nomFichier) ;

                           monFichierZip.putNextEntry(monEntreeZip) ;

 

                           // créer le flot de sortie vers le flot de sortie zip

                           DataOutputStream monFichier

                                               = new DataOutputStream (

                                                           new BufferedOutputStream

                                                                                   (monFichierZip)) ;

                           // écrire les nb premiers dans le fichier

                           for (int i=0 ; i<premiers.length ; i++)

                                   monFichier.writeLong(premiers[i]) ;

                           monFichier.flush() ;   // s’assurer que tout est écrit

                           monFichierZip.closeEntry() ; //terminer l’entrée zip

                           monFichier.close() ;   // fermer le flot de fichier

 

                           System.out.println(« Taille du fichier = »  +

                                                           monFichier.size()) ;

                           System.out.println(« Taille du fichier compressé = »

                                               + monEntreeZip.getCompressedSize()) ;

                        }

                        catch (IOException e)

                                   System.out.println(« IOException  » + e

                                                                                   + «  est survenue ») ;

            }

}

 

Rappels sur flots d’entrée et flots d’objets :

Ø    Les opérations de flots d’entrée d’octets sont définies par des sous-classes de la classe abstraite InputStream, et celles sur les flots d’entrée de caractères par les sous-classes de Reader

Ø    Les classes de flots d’entrée filtrés complètent les classes de flots de sortie filtrés

Ø    La classe System de java.lang définit les membres in, out et err (de type PrintStream) pour représenter respectivement le flot d’entrée standard et les flots de sortie standard et d’erreur standard

Ø    La classe RandomAccessFile  permet de lire et d’écrire dans un fichier

Ø    On peut utiliser la classe StreamTokenizer pour lire des données formatées à partir d’un flot

En outre :

Ø    La sérialisation d’objets est prise en charge via les classes ObjectOutputStream  et ObjectInputStream

Ø    Les objets sont écrits dans un fichier en appelant la méthode writeObject() de l’objet ObjectOutputStream correspondant au fichier

Ø     Les objets sont lus dans un fichier en appelant la méthode readObject() de l’objet ObjectInputStream correspondant au fichier

 

Exercice 3 : lecture à partir du fichier premiers.bin

1) Créez un programme permettant de lire un fichier de nombres premiers tel qu’il aurait été créé dans l’exercice 1.

2) Affichez à l’écran ces données à l’aide d’un flot de caractères.

 

F  Pour la question 1) le principe est analogue à ce qui a été fait pour écrire les données binaires dans un flot de sortie : il faut créer un objet DataInputStream à partir d’un FileInputStream.

Pour la question 2) utiliser un objet FormatWriter qui gère l’affichage à l’écran.

 

Exercice 4:  (variante) lecture à partir du fichier compressé.

F  on créera un ZipInputStream (intitulé  monFichierZip) à partir du FileInputStream et un ZipEntry à partir de monFichierZip  en faisant appel à getNextEntry().

Ensuite on crée un DataInputStream bufferizé à partir de monFichierZip . Le reste est inchangé.

 


Eléments de correction pour l’exercice 3

question 1) :

import java.io.* ;

public class LirePremiers {

            public static void main (String [ ] args ) {

                        try {

                           String nomDuRepertoire = « ../DonneesInutilisables » ;

                           String nomFichier = « premiers.bin » ;

 

                           File mesNbPremiers = new File (nomDuRepertoire,

                                                                                               nomFichier) ;

 

                           DataInputStream premiersInt

                                                = new DataInputStream (

                                                                       new FileInputStream (

                                                                                   mesNbPremiers))) ;

                        // Ici, le code permettant de lire les nombres

                        // les nombres premiers dans le flot précédant

                        // et de les afficher à l’écran (question 2)

 

                        out.close() ;

                        premiersInt.close() ;

                        }

                        catch (FileNotFoundException e) {

                                   System.err.println(e);

                                   return ;

                        }

                        catch (IOException e) { // Exception de lecture de fichier

                                   System.err.println(« Erreur lecture fichier d’entrée  »

                                                                                   + e);

                                   return ;

                        }

            }

}

question 2) :

                        // Créer un flot de sortie de caractères formaté par défaut

                        FormatWriter out = new FormatWriter (

                                                           new BufferedWriter (

                                                           new FileWriter (FileDescriptor.out))) ;

 

                        long [ ] Premiers = new long [6] ; // tableau d’une ligne                                              boolean EOF = false ;  // indicateur de fin de fichier

 

                        while ( !EOF) {

                                   int index = 0 ;// index pour stocker les nombres premiers

                                   try {

                                               // remplir la ligne avec les nbs venant du fichier

                                               for (index = 0 ; index < Premiers.length ; index++)

                                                           Premiers [index] = premiersInt.readLong() ;

                                   }

                                   catch (EOFException e) {

                                               EOF = true ;     // mettra fin à la boucle

                                   }

                                   // Afficher les nombres premiers qui sont

                                   // dans le tableau Premiers sur une ligne de sortie

                                   for (int j = 0 ; j < index ; j++)

                                               out.print(Premiers[j]) ;

                                   out.println() ;    // passer à la ligne suivante

                        }