56
1 Fichers Binaires, Accès Direct et Objets

1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

Embed Size (px)

Citation preview

Page 1: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

1

Fichers Binaires, Accès Direct et Objets

Page 2: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

2

Données binaires.

Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce faire nous utilisons DataInputStream et DataOutputStream.

Ces classes sont construites pour traiter des données binaires et tous les types de base de Java.

Page 3: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

3

Exemple: Écrire un int et un double pour les relire ensuite.

import java.io.*;public class TestEcrireLireBinaire{

public static void main(String[] args){int k = 50;double x = Math.PI;String NOM = "binaire.dat";DataOutputStream dos = new DataOutputStream(new

FileOutputStream(NOM));

dos.writeInt( k );dos.writeDouble( x );dos.close();

DataInputStream dis = new DataInputStream(new FileInputStream(NOM));

k = dis.readInt();x = dis.readDouble();dis.close();

}}

Page 4: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

4

Il n'existe pas de méthode readString() ni de méthode writeString() dans les classes Data….

Pour lire ou écrire des String nous devons utiliser les méthodes readChar(), writeChar(), writeChars(), readUTF() et writeUTF().

UTF signifie "Unicode Text Format". L'usage des méthodes contenant le sigle UTF n'implique pas un transfert de deux octets par caractère transmis. Le nombre d'octets transmis varie selon le code du caractère.

Les méthodes contenant le sigle Char transmettent toujours deux octets par caractère.

Page 5: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

5

Les méthodes disponibles pour la lecture sont: readXX() où XX est une des valeurs suivantes: Boolean, Byte, Char, Double, Float, Int, Long, Short et UTF.

Les méthodes disponibles pour l'écriture sont: writeXX() où XX est une des valeurs suivantes: Boolean, Byte, Char, Double, Float, Int, Long, Short, UTF, Bytes, Chars.

Les méthodes writeBytes() et writeChars() acceptent des String comme arguments, par exemple writeBytes("Allo le monde").

La méthode flush() est aussi disponible à la sortie pour vider le tampon de données.

Page 6: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

6

Une différence importante entre ce type de fichier et les fichiers de texte est que les fichiers dits binaires ne contiennent pas de caractère EOF car ce caractère ne pourrait pas être distingué d'une donnée binaire.

Page 7: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

7

Il est très important de concevoir les deux méthodes d'entrée et de sortie (lireBinaire et ecrireBinaire) ensemble car l'une doit être absolument compatible avec l'autre.

Toute modification à une de ces méthodes doit immédiatement être effectuée dans l'autre car les données binaires sont littérales et ne peuvent être interprétées que par le programme qui les lit et les écrit.

En effet, une suite de 64 uns et zéros peut être interprétée comme deux int ou bien un long ou encore un double!

Page 8: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

8

Le code plus bas est un exemple plus complet dans lequel nous lisons séquentiellement un fichier au complet vers un tableau en mémoire.

Dans le même exemple, nous écrivons séquentiellement tout le tableau dans un fichier binaire évidemment compatible avec le fichier de lecture.

Page 9: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

9

import java.io.*;import java.io.Serializable;public class Employe implements Serializable{

private static final int LONG_NOM = 26; private int ID;

private String nom;private int age;private double salaire;

public static int size(){return (4 + LONG_NOM*2 + 4 + 8); } public Employe(){ this(0, "", 0, 0); }

public Employe( int leID, String leNom, int leAge, double leSalaire){set(leID, leNom, leAge, leSalaire);

}public Employe(String ligne){

set( ligne );}

public int getID() {return ID;} public String getNom() {return nom;} public int getAge() {return age;} public double getSalaire(){return salaire;} public void setID(int k) {ID = k;} public void setNom(String leNom){ if(leNom == null) leNom = "";

nom = (leNom + reproduire(' ', LONG_NOM)).substring(0, LONG_NOM); } public void setAge(int k) {age = k;} public void setSalaire(double d){salaire = d;}

public void set( int leID, String leNom, int leAge, double leSalaire){setID(leID);

setNom(leNom);setAge(leAge);setSalaire(leSalaire);

}

Page 10: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

10

public void set( String ligne ){set(Integer.parseInt( ligne.substring(0, 6).trim()),

ligne.substring(7, 33), Integer.parseInt( ligne.substring(34, 36).trim()), Double.parseDouble(ligne.substring(37))

);}

public String toString(){String str = (ID + reproduire(' ', 6)).substring(0, 6) + " ";str += (nom + reproduire(' ', LONG_NOM)).substring(0, LONG_NOM) + " ";str += (age + reproduire(' ', 2)).substring(0, 2) + " ";String sal = salaire + reproduire('0', 2);str += sal.substring(0, sal.indexOf(".")+3);return str;

}

String reproduire( char c, int n){if( n <= 0 )

return "";char table[] = new char[n];for(int k=0; k<n; k++)

table[k] = c;return new String(table);

}

Page 11: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

11

public void ecrireBinaire( DataOutputStream dos) throws IOException {

dos.writeInt(ID);dos.writeChars(completerString(nom, LONG_NOM));

//exactement LON_NOM caracdos.writeInt(age);dos.writeDouble(salaire);

}

public void lireBinaire( DataInputStream dis) throws IOException {

ID = dis.readInt();nom = readChars(dis, LONG_NOM);age = dis.readInt();salaire = dis.readDouble();

}

Page 12: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

12

public void ecrireBinaire( RandomAccessFile raf) throws IOException {

raf.writeInt(ID);raf.writeChars(completerString(nom,LONG_NOM));

//exactement LONG_NOM carac.raf.writeInt(age);raf.writeDouble(salaire);

}

public void lireBinaire( RandomAccessFile raf) throws IOException {

ID = raf.readInt();nom = readChars(raf, LONG_NOM);age = raf.readInt();salaire = raf.readDouble();

}

Page 13: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

13

private String readChars(RandomAccessFile raf, int longueur) throws IOException { char[] chr = new char[longueur]; for(int k=0; k<longueur; k++)

chr[k] = raf.readChar(); return new String(chr); }

String completerString(String str, int longueur){if( longueur <=0 )

return str;return (str+reproduire(' ', longueur)).substring(0, longueur);

}

public String afficher(int k){ String str = (""+(1000+k+1)).substring(1) + " :: " + toString(); System.out.println(str); return str; }} // Fin de la classe Employe

Page 14: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

14

/////////////////////////////////////////////////////////////////////import java.io.*;import java.io.Serializable;public class TousEmploye implements Serializable{ public static final String CHEMIN = "C:/TestFichiers/";

public static final int MAX_EMPLOYE = 1000;Employe vEmp[] = new Employe[MAX_EMPLOYE];;int nbvEmp = 0;public TousEmploye(String nomFichier){

lireToutFichier( nomFichier );}void lireToutFichier( String nomFichier ){

if( nomFichier.indexOf(".txt") > 0 )lireToutFichierTexte( nomFichier );

else if( nomFichier.indexOf(".dat") > 0 )lireToutFichierBinaire( nomFichier );

else System.out.println("Nom illégal");

}

Page 15: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

15

public void afficherTous(String titre){ System.out.println("\n\n" + titre); for(int k=0; k<nbvEmp; k++){ if( k%20 == 0 ) System.out.println(

"# enrg ID NOM AGE SALAIRE \n" +

"====== ====== ========================== == =========");

vEmp[k].afficher( k ); } System.out.println();

}

Page 16: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

16

void lireToutFichierTexte( String nomFichier ){BufferedReader br;int k;System.out.println("lireToutFichierTexte: DEBUT");

try{ br = new BufferedReader(new FileReader(nomFichier)); } catch(FileNotFoundException fnfe){ System.out.println("Nom de fichier inexistant "); System.exit(1); } k = 0; try{ String ligne = br.readLine(); while( ligne != null){ vEmp[k++] = new Employe( ligne ); ligne = br.readLine(); } nbvEmp = k; br.close(); }catch(IOException ioe){ nbvEmp = k; System.out.println("Erreur d'entrée-sortie"); } System.out.println("lireToutFichierTexte: FIN"); return;

}

Page 17: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

17

void lireToutFichierBinaire( String nomFichier ){DataInputStream dis;int k;

System.out.println("lireToutFichierBinaire: DEBUT");try{ dis = new DataInputStream( new FileInputStream(nomFichier));

}catch(FileNotFoundException e){ System.out.println("Nom de fichier inexistant ");

System.exit(1);}k = 0;try{

while( true ){vEmp[k] = new Employe();vEmp[k].lireBinaire(dis);k++;

}// Tout code placé ici est inaccessible.

}catch( EOFException e ){ nbvEmp = k; System.out.println("lireToutFichierBinaire: nbvEmp=" +nbvEmp); }catch( IOException e){ nbvEmp = k; System.out.println("Erreur d'entrée-sortie"); System.exit(2); } try{ dis.close(); }catch( IOException e){ System.out.println("Erreur d'entrée-sortie");

System.exit(2) ; } System.out.println("lireToutFichierBinaire: FIN"); return;

}

Page 18: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

18

void ecrireToutFichierBinaire( String nomFichier ){DataOutputStream dos;int k;

System.out.println("ecrireToutFichierBinaire: DEBUT");try{

dos = new DataOutputStream( new FileOutputStream(nomFichier)); }catch(FileNotFoundException e){ System.out.println("Nom de fichier inexistant "); System.exit(1); } try{

k = 0;while( k < nbvEmp ){

vEmp[k].ecrireBinaire(dos);k++;

}dos.flush();dos.close();

}catch( IOException e){ System.out.println("Erreur d'entrée-sortie");

System.exit(2) ; } System.out.println("ecrireToutFichierBinaire: FIN"); return;

}

Page 19: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

19

public static void main( String args[]){TousEmploye teA = new TousEmploye( CHEMIN + "Employe.txt" );

teA.afficherTous( "Après la lecture initiale" );teA.ecrireToutFichierBinaire( CHEMIN + "Employe.dat" );

teA = null; // Ce traitement détruit entièrement l'objet teA existant

// Ce constructeur provoque la lecture du fichier binaireteA = new TousEmploye( CHEMIN + "Employe.dat" );teA.afficherTous( "Après l'écriture et la lecture binaires" );}

}

Page 20: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

20

La sérialisation

La sérialisation permet la conversion d'objets en mémoire vers des objets externes et la conversion d'objets externes vers des objets en mémoire. Les résultats de ces conversions sont transmis en série un octet à la fois. Pour toutes fins pratiques, cela permet de lire et d'écrire des objets, qui peuvent être très complexes.

La lecture et l'écriture des objets se fait à l'aide de ObjectInputStream et ObjectOutputStream. Ces classes permettent donc de sauvegarder des objets sur disque et aussi de transmettre des objets à travers un réseau.

Page 21: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

21

Lorsqu'un objet écrit via la sérialisation est composé d'un autre objet, celui-ci est aussi sérialisé.

De cette façon des objets très complexes peuvent être écrits sans effort particulier de programmation autre que de déclarer tous ces objets sérialisables.

Page 22: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

22

Par exemple si les classes Employe et TousEmployes vues précédemment sont déclarées ainsi:

import java.io.Serializable;

public class Employe implements Serializable{ . . . }

public class TousEmployes implements Serializable { . . . }

alors, il est possible de les sérialiser c'est-à-dire de les écrire et

de les lire presque sans effort comme dans l'exemple qui suit.

Page 23: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

23

import java.io.*;public class TestSerialize{

public static void main( String args[] ){// Créer l'objet teA comme dans l'exemple précédent.

TousEmploye teA = new TousEmploye( TousEmploye.CHEMIN + "Employe.txt" );// Traiter l'objet teA selon le problème à résoudre.teA.afficherTous("Test de sérialisation\nAprès la lecture initiale");// Sauvegarder l'objet teA à l'aide de la sérialisation

ObjectOutputStream oos;String leFichier = TousEmploye.CHEMIN +

"Serie.dat";

Page 24: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

24

System.out.println("Écriture par sérialisation: DEBUT"); try{ oos = new ObjectOutputStream(new

FileOutputStream( leFichier )); }catch(IOException ioe){ System.out.println( "Erreur d'entrée-sortie"); return; } try{ oos.writeObject( teA ); oos.flush(); oos.close(); }catch(IOException ioe){ System.out.println( "Erreur d'entrée-sortie"); System.exit(2); } System.out.println("Écriture par sérialisation: FIN");

// Traitements diversteA = null; // Ce traitement détruit entièrement l'objet teA

existant

Page 25: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

25

// Lire l'objet teA (conservé précédemment) à l'aide de la sérialisation.ObjectInputStream ois;

System.out.println("Lecture par sérialisation: DEBUT"); try{ ois = new ObjectInputStream(new FileInputStream( leFichier )); }catch(StreamCorruptedException sce){ System.out.println( "Le fichier est corrompu."); System.exit(3); }catch(IOException ioe){ System.out.println( "Erreur d'entrée-sortie"); System.exit(2); } try{ teA = (TousEmploye)ois.readObject();

ois.close(); }catch(ClassNotFoundException ioe){ System.out.println( "Nom de fichier inexistant."); System.exit(1); }catch(IOException ioe){ System.out.println( "Erreur d'entrée-sortie"); System.exit(2); } System.out.println("Lecture par sérialisation: FIN");

teA.afficherTous("Après l'écriture et la lecture binaires");}

}

Page 26: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

26

Nous voyons que l'usage de la sérialisation réduit la difficulté de lire et d'écrire un objet, qui peut être très complexe, à celle de lire ou d'écrire un type de base.

Ici nous avons écrit d'un seul coup tout le tableau d'Employe (vEmp) ainsi que son nombre d'Employe (nbvEmp).

Il est possible d'utiliser la sérialisation pour lire et écrire enregistrement par enregistrement (Employe par

Employe ici).

En exercice !!!

Page 27: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

27

L'accès direct à l'information

Un fichier est considéré en Java comme une séquence d'octets. Chacun des octets étant adressable. L'adresse d'un octet du fichier est souvent appelé "la position dans le fichier".

Page 28: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

28

Afin de lire ou écrire à une position particulière dans un fichier nous utilisons la classe RandomAccesFile.

Cette classe admet le positionnement du curseur de fichier à n'importe quelle position dans le fichier ou à la fin du fichier.

Ce qui permet l'écriture de fichiers indexés et le traitement du fichier un peu comme dans une base de données.

Page 29: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

29

Il est difficile de se retrouver dans un fichier à accès direct si les enregistrements sont de longueurs variables. Dans ce cas la construction d'un index est une bonne solution.

La création d'un tel fichier contenant des enregistrements de longueur variable est faite en écrivant les enregistrements séquentiellement. Chaque enregistrement écrit voit sa position consignée dans un index et est accompagné d'une clef permettant de le retrouver.

L'index est ensuite écrit dans un fichier séparé.

Page 30: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

30

Si les enregistrements sont de longueur fixe, il est facile de s'y retrouver car à l'aide d'un calcul simple la position d'un enregistrement quelconque peut être retrouvée

position = noEnregistrement * longueurEnregistrement

L'exemple plus bas utilise le fait que les enregistrements de la classe Employe sont de longueur fixe et mesurent Employe.size() (soit 68) caractères.

Page 31: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

31

Une façon très simple de créer un fichier d'accès direct dont les enregistrements sont de longueur fixe est de l'initialiser avec des enregistrements vides. Ensuite on écrit les enregistrements véritables à l'aide de l'accès direct.

Une autre façon de le créer est possible si nous disposons d'une table d'enregistrements, souvent gardée dans un fichier texte, ordonnée sur la clef de recherche du fichier (par exemple le ID dans le cas du fichier "Employe.txt" utilisé en exemple).

Dans ce cas le fichier d'accès direct est créé en l'écrivant séquentiellement à partir des enregistrements de la table initiale.

Page 32: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

32

RandomAccessFile implémente les interfaces DataInput et DataOutput ce qui donne à cette classe toutes les propriétés des classes vues précédemment soient DataInputStream et DataOutputStream.

Les principales méthodes sont:void seek(long location) qui permet le positionnement

du curseur à la location désirée transmise par le paramètre location.

int skipBytes( int combien) qui permet de déplacer le curseur vers l'avant du nombre d'octets spécifié par le paramètre combien.

long getFilePointer() qui retourne la position du curseur.

Page 33: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

33

La classe RandomAccessFileLa classe RandomAccessFile est encore plus intéressante à retenir puisqu'elle permet de faire à peu près tout avec un fichier. Le constructeur RandomAccessFile(String name, String mode) s'emploie avec une chaîne de caractères contenant le nom de fichier suivi du mode d'accès "r" pour lecture ou "rw" pour lecture et écriture.

Le constructeurRandomAccessFile(File file, String mode) fait de même à partir de l'objet File et d'un mode r ou rw.

Une fois ainsi créé, un fichier RandomAccess s'attaque avec les méthodes

suivantes MéthodeDescription

close()ferme le fichiergetFD()obtient un objet FileDescriptor pour le fichiergetFilePointer()obtient la position du pointeur sur le fichierlength()retourne la longueur du fichierread()lecture de donnéesreadBoolean()lit un booleanreadByte()lit un octetreadChar()lit un charreadDouble()lit un double (virgule flottante)readFloat()lit un float

Page 34: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

34

readFully()lit des données dans un tableau en remplissant celui-cireadInt()lit un entierreadLine()lit une lignereadLong()lit un longreadShort()lit un short integerreadUnsignedByte()lit un octet non signéreadUnsignedShort()lit un short integer non signéreadUTF()lit une chaîne de type UTFseek()positionne le pointeur dans un fichierskipBytes()saute un nombre donné d'octetswrite()écrit vers le fichierwriteBoolean()écrit un booelanwriteByte()écrit un octetwriteBytes()écrit une chaîne sous forme d'octets

Page 35: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

35

writeChar()écrit un char

writeChars()écrit une chaîne sous forme de char

writeDouble()écrit un double

writeFloat()écrit un float

writeInt()écrit un int

writeLong()écrit un long

writeShort()écrit un short int

writeUTF()écrit une chaîne de type UTF

Page 36: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

36

/** FICHIERS ACCÈS DIRECT */import java.io.*;import javax.swing.*;public class Etudiant { int netud; String nom; float note; static RandomAccessFile sortie; final int tnom=20; final int t_enreg=4+(tnom*2)+8;public static void creer_fichier(RandomAccessFile sortie) throws IOException { File f=new File("c:etud.dat"); sortie=new RandomAccessFile("c:etud.dat","rw"); int netudb=0; int i; String nomb=" "; ou f float noteb=0.0f; for(i=0;i<20;i++) { sortie.seek(i*t_enreg); sortie.writeInt(netudb); sortie.writeUTF(nomb); sortie.writeFloat(noteb); } sortie.close(); }

Page 37: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

37

public static void ajouter(RandomAccessFile sortie) throws IOException

{ int i; int netud; String nom; float note; netud=Integer.parseInt(JOptionPane.showInputDialog("Entrer le

numero de l'etudiant:")); nom=JOptionPane.showInputDialog("Entrer le nom de

l'etudiant:"); note=Float.parseFloat(JOptionPane.showInputDialog("Entrer la

note de l'etudiant:")); sortie.seek((netud/100-1)*t_enreg);//seq: 100, 200, 300,…. sortie.writeInt(netud); sortie.writeUTF(nom); sortie.writeFloat(note); }

Page 38: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

38

public static void rechercher(RandomAccessFile sortie) throws IOException

{ int pos; int netud; String nom; double note; int t_enreg; netud=Integer.parseInt(JOptionPane.showInputDialog("Entrer le

numero de l'etudiant a rechercher:")); pos=((netud/100)-1)*t_enreg; sortie.seek(pos); netud=sortie.readInt(); nom=sortie.readUTF(); note=sortie.readFloat(); JOptionPane.showMessageDialog(null,"Numero:"+ netud +"\n" +

"Nom:"+ nom + "\n" +"Note"+ note); }

Page 39: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

39

public static void afficher(RandomAccessFile sortie) throws IOException { int netud; String nom; double note; int i; File f=new File("c:etud.dat"); for(i=0;i<20;i++) { sortie.seek(i*t_enreg); netud=sortie.readInt(); if(netud!=0) { nom=sortie.readUTF(); note=sortie.readFloat(); JOptionPane.showMessageDialog(null,"Numero:"+ netud +"\n" + "Nom:"+ nom + "\n"

+"Note"+ note); } else {nom=sortie.readUTF(); note=sortie.readFloat();} } }

On aurait pu utiliser skipBytes

Page 40: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

40

public static void main(String[] args)throws IOException { sortie =new RandomAccessFile("c:etud.dat","rw"); InputStreamReader lecteur=new InputStreamReader(System.in); BufferedReader clavier=new BufferedReader(lecteur); String chaine; int choix=0; do { choix=Integer.parseInt(JOptionPane.showInputDialog("\n 1-Creer le fichier\n 2-

Ajout d'enregistrement" +"\n 3-Recherche d'un etudiant\n 4-Affichage\n 5-Quitter\nEntrer votre

choix:")); switch (choix){ case 1:creer_fichier(sortie);break; case 2:ajouter(sortie);break; case 3:rechercher(sortie);break; case 4:afficher(sortie);break; case 5:System.exit(0) ; } }while(true); }}

Page 41: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

41

/** EXEMPLE PLUS COMPLET * Title: Tests sur les divers fichiers<p> * Description: Tests * 1- Fichiers binaires * 2- L'accès direct*/import java.io.*;import java.io.RandomAccessFile;public class TestEmployeAccesDirect { protected static final String NOM_FICHIER = TousEmploye.CHEMIN + "Employe.dat"; protected String nomFichier; protected RandomAccessFile raf; protected int premierID; protected int dernierID; public TestEmployeAccesDirect(String nomFichier, String mode) throws IOException{ this.nomFichier = nomFichier; raf = new RandomAccessFile(nomFichier, mode); } public long getPositionPremier()throws IOException{ Employe emp = new Employe(); raf.seek(0); long lPos = raf.getFilePointer(); emp.lireBinaire(raf); premierID = emp.getID(); return lPos; }

Page 42: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

42

public long getPositionDernier()throws IOException{ Employe emp = new Employe(); long lPos = raf.length() - Employe.size(); if(lPos < 0 ) return lPos; raf.seek(lPos); emp.lireBinaire(raf); dernierID = emp.getID(); return lPos; }

public long positionnerCurseur(int ID)throws IOException{ if(ID < premierID) throw new IOException("ID illegal. "); if(dernierID < ID) genererEnregistrements(ID - dernierID); raf.seek((long)(ID-premierID)*Employe.size()); return raf.getFilePointer(); }

ID= 123468

premierID= 123456

Num enreg= 12

Correspond à enreg#013

Commence à compter à partir de zéro.

Page 43: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

43

public void genererEnregistrements(int nombre)throws IOException{ Employe emp = new Employe(); raf.seek(raf.length()); for(; nombre>0; nombre--){ emp.setID(++dernierID); emp.ecrireBinaire(raf); } }

public void afficherToutFichierReculons(String titre)throws IOException{ System.out.println("\n\n" + titre); getPositionPremier(); getPositionDernier(); Employe emp = new Employe(); int nbLignes = 0; for(int ID=dernierID; ID>=premierID; ID--){ if( nbLignes++%20 == 0 )

System.out.println("# enrg ID NOM AGE SALAIRE \n" +

"====== ====== ========================== == =========");

positionnerCurseur(ID); emp.lireBinaire(raf); emp.afficher(ID - premierID); } System.out.println(); }

Page 44: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

44

public static void main(String[] args) { // Création de l'objet à partir d'un fichier texte TousEmploye teA = new TousEmploye( TousEmploye.CHEMIN + "Employe.txt" ); teA.afficherTous( "Test fichiers accès direct\nAprès la lecture initiale" ); teA.ecrireToutFichierBinaire( NOM_FICHIER ); teA = null; // Ce traitement détruit entièrement l'objet teA existant // À ce point-ci le fichier binaire étant créé, il est possible de l'accéder // à l'aide d'un traitement utilisant les méthodes d'accès direct Employe emp = new Employe(); try{ TestEmployeAccesDirect tad = new TestEmployeAccesDirect(NOM_FICHIER, "rw"); tad.getPositionPremier(); System.out.println("Le premier ID: " + tad.premierID); tad.getPositionDernier(); System.out.println("Le dernier ID: " + tad.dernierID);

tad.positionnerCurseur(123470); emp.lireBinaire(tad.raf); emp.afficher(emp.getID() - tad.premierID); emp.setSalaire(emp.getSalaire()+500000.0); emp.setAge(emp.getAge()+10); tad.positionnerCurseur(123470); emp.ecrireBinaire(tad.raf);

Page 45: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

45

emp.afficher(emp.getID() - tad.premierID); tad.positionnerCurseur(123459); emp.lireBinaire(tad.raf); emp.afficher(emp.getID() - tad.premierID); tad.positionnerCurseur(123470); emp.lireBinaire(tad.raf); emp.afficher(emp.getID() - tad.premierID); tad.positionnerCurseur(tad.dernierID + 4); tad.afficherToutFichierReculons("Fichier Accès direct affiché du

dernier au premier enregistrement"); tad.positionnerCurseur(1000); }catch(IOException ioe){ System.out.println("Une exception: " + ioe.getMessage()); System.out.println("\nCette erreur prévue d'avance ici termine

cet exemple.");}

}}

Page 46: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

46

Résultats de l'exemple de l'accès direct à l'information

Fichier Employe.txt

123456 Dieudonné de la Trémoïlle 92 123456.78123457 Dieudonné de la Trémoïlle1 82 103456.78123458 Dieudonné de la Trémoïlle2 72 102456.78123459 Dieudonné de la Trémoïlle3 62 101456.78123460 Dieudonné de la Trémoïlle4 52 100456.78123461 Dieudonné de la Trémoïlle5 42 100356.78123462 Dieudonné de la Trémoïlle6 32 100256.78123463 Dieudonné de la Trémoïlle7 22 100156.78123464 Dieudonné de la Trémoïlle8 2 100056.78123465 Dieudonné de la Trémoïlle 91 123456.78123466 Dieudonné de la Trémoïlle1 81 103456.78123467 Dieudonné de la Trémoïlle2 71 102456.78123468 Dieudonné de la Trémoïlle3 61 101456.78123469 Dieudonné de la Trémoïlle4 51 100456.78123470 Dieudonné de la Trémoïlle5 41 100356.78123471 Dieudonné de la Trémoïlle6 31 100256.78123472 Dieudonné de la Trémoïlle7 21 100156.78123473 Dieudonné de la Trémoïlle8 1 100056.78123474 Dieudonné de la Trémoïlle 93 123456.78123475 Dieudonné de la Trémoïlle1 83 103456.78123476 Dieudonné de la Trémoïlle2 73 102456.78123477 Dieudonné de la Trémoïlle3 63 101456.78123478 Dieudonné de la Trémoïlle4 53 100456.78123479 Dieudonné de la Trémoïlle5 43 100356.78123480 Dieudonné de la Trémoïlle6 33 100256.78123481 Dieudonné de la Trémoïlle7 23 100156.78

Page 47: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

47

DÉBUT Résultats de la section L'accès direct à l'informationlireToutFichierTexte: DEBUTlireToutFichierTexte: FINTest fichiers accès directAprès la lecture initiale# enrg ID NOM AGE SALAIRE ====== ====== ========================== == =========001 :: 123456 Dieudonné de la Trémoïlle 92 123456.78002 :: 123457 Dieudonné de la Trémoïlle1 82 103456.78003 :: 123458 Dieudonné de la Trémoïlle2 72 102456.78004 :: 123459 Dieudonné de la Trémoïlle3 62 101456.78005 :: 123460 Dieudonné de la Trémoïlle4 52 100456.78006 :: 123461 Dieudonné de la Trémoïlle5 42 100356.78007 :: 123462 Dieudonné de la Trémoïlle6 32 100256.78008 :: 123463 Dieudonné de la Trémoïlle7 22 100156.78009 :: 123464 Dieudonné de la Trémoïlle8 2 100056.78010 :: 123465 Dieudonné de la Trémoïlle 91 123456.78011 :: 123466 Dieudonné de la Trémoïlle1 81 103456.78012 :: 123467 Dieudonné de la Trémoïlle2 71 102456.78013 :: 123468 Dieudonné de la Trémoïlle3 61 101456.78014 :: 123469 Dieudonné de la Trémoïlle4 51 100456.78015 :: 123470 Dieudonné de la Trémoïlle5 41 100356.78016 :: 123471 Dieudonné de la Trémoïlle6 31 100256.78017 :: 123472 Dieudonné de la Trémoïlle7 21 100156.78018 :: 123473 Dieudonné de la Trémoïlle8 1 100056.78019 :: 123474 Dieudonné de la Trémoïlle 93 123456.78020 :: 123475 Dieudonné de la Trémoïlle1 83 103456.78# enrg ID NOM AGE SALAIRE ====== ====== ========================== == ========= 021 :: 123476 Dieudonné de la Trémoïlle2 73 102456.78 022 :: 123477 Dieudonné de la Trémoïlle3 63 101456.78 023 :: 123478 Dieudonné de la Trémoïlle4 53 100456.78 024 :: 123479 Dieudonné de la Trémoïlle5 43 100356.78 025 :: 123480 Dieudonné de la Trémoïlle6 33 100256.78 026 :: 123481 Dieudonné de la Trémoïlle7 23 100156.78 ecrireToutFichierBinaire: DEBUT ecrireToutFichierBinaire: FIN

Page 48: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

48

Le premier ID: 123456Le dernier ID: 123481015 :: 123470 Dieudonné de la Trémoïlle5 41 100356.78015 :: 123470 Dieudonné de la Trémoïlle5 51 600356.78004 :: 123459 Dieudonné de la Trémoïlle3 62 101456.78015 :: 123470 Dieudonné de la Trémoïlle5 51 600356.78Fichier Accès direct affiché du dernier au premier enregistrement# enrg ID NOM AGE SALAIRE ====== ====== ========================== == ========= 030 :: 123485 0 0.00 029 :: 123484 0 0.00 028 :: 123483 0 0.00 027 :: 123482 0 0.00 026 :: 123481 Dieudonné de la Trémoïlle7 23 100156.78 025 :: 123480 Dieudonné de la Trémoïlle6 33 100256.78 024 :: 123479 Dieudonné de la Trémoïlle5 43 100356.78 023 :: 123478 Dieudonné de la Trémoïlle4 53 100456.78 022 :: 123477 Dieudonné de la Trémoïlle3 63 101456.78 021 :: 123476 Dieudonné de la Trémoïlle2 73 102456.78 020 :: 123475 Dieudonné de la Trémoïlle1 83 103456.78 019 :: 123474 Dieudonné de la Trémoïlle 93 123456.78 018 :: 123473 Dieudonné de la Trémoïlle8 1 100056.78 017 :: 123472 Dieudonné de la Trémoïlle7 21 100156.78 016 :: 123471 Dieudonné de la Trémoïlle6 31 100256.78 015 :: 123470 Dieudonné de la Trémoïlle5 51 600356.78 014 :: 123469 Dieudonné de la Trémoïlle4 51 100456.78 013 :: 123468 Dieudonné de la Trémoïlle3 61 101456.78 012 :: 123467 Dieudonné de la Trémoïlle2 71 102456.78 011 :: 123466 Dieudonné de la Trémoïlle1 81 103456.78

Page 49: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

49

# enrg ID NOM AGE SALAIRE ====== ====== ========================== == =========010 :: 123465 Dieudonné de la Trémoïlle 91 123456.78009 :: 123464 Dieudonné de la Trémoïlle8 2 100056.78008 :: 123463 Dieudonné de la Trémoïlle7 22 100156.78007 :: 123462 Dieudonné de la Trémoïlle6 32 100256.78006 :: 123461 Dieudonné de la Trémoïlle5 42 100356.78005 :: 123460 Dieudonné de la Trémoïlle4 52 100456.78004 :: 123459 Dieudonné de la Trémoïlle3 62 101456.78003 :: 123458 Dieudonné de la Trémoïlle2 72 102456.78002 :: 123457 Dieudonné de la Trémoïlle1 82 103456.78001 :: 123456 Dieudonné de la Trémoïlle 92 123456.78Une exception: ID illegal. Cette erreur prévue d'avance ici termine cet exemple.FIN Résultats de la section L'accès direct à l'information

Page 50: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

50

A JFileChooser is a dialog to select a file or files. Thereturn value of the three methods is one of the following: JFileChooser.CANCEL_OPTION, if the user clicks Cancel.

JFileChooser.APPROVE_OPTION, if the user click an OK/Open/Save button.

JFileChooser.ERROR_OPTION, if the user closes the dialog

A return value of JFileChooser.APPROVE_OPTION, indicates that you can call its getSelectedFile or getSelectedFiles methods: public java.io.File getSelectedFile ()public java.io.File[] getSelectedFiles ()    

Page 51: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

51

import java.io.*;import javax.swing.JFileChooser;class choixFichier{ public static void main(String[] args) throws IOException { JFileChooser fenetre = new JFileChooser(); BufferedWriter sortie; File fichier; if (fenetre.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {

fichier = fenetre.getSelectedFile();sortie = new BufferedWriter(new FileWriter(fichier.getPath(), true));sortie.write("BONJOUR");sortie.close();

} System.exit(0); }}

Page 52: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

52

Page 53: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

53

La classe File permet de gérer les fichiers et les dossiers de façon externe (nom,taille, existence, type, etc...). Constructeurs et méthodesConstructeursFile(File d, String n)

d est le dossier du fichier, n est son nom. File(String n)

n est le nom du fichier. Méthodes principalesboolean exists()

indique si le fichier existe. String getCanonicalPath()

renvoie le chemin complet d'accès au fichier sous forme canonique (sans . ou ..). String getName()

renvoie le nom du fichier. boolean isDirectory()

indique s'il s'agit d'un dossier boolean isFile()

indique s'il s'agit d'un vrai fichier int length()

renvoie la taille du fichier String[] list()

renvoie la liste des fichiers d'un dossier sous forme de tableau de chaînes.

Page 54: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

54

Exemple 1:import java.io.*;import javax.swing.*;public class dirContenu { public static void main(String[] args) throws Exception { String rep; rep=JOptionPane.showInputDialog("Entrer le repertoire :"); if (rep.length() == 0) { System.out.println("Veuillez saisir un dossier !"); System.exit(0); } File f = new File(rep); String [] files = f.list(); for(int i =0; i < files.length; i++) { if (new File(rep + "\\" + files[i]).isDirectory()) { System.out.print("Rep : "); } else { System.out.print("Fil : "); } System.out.println(rep + "\\" + files[i]); } }}

Page 55: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

55

Exemple 2:import java.io.*;import javax.swing.JOptionPane;class testerFile{ public static void main(String[] args) throws IOException { File repertoire; File fichier=null; File nouveauFichier; String[] listeFichiers; BufferedWriter sortie; String rep; rep=JOptionPane.showInputDialog("Entrer le repertoire :"); repertoire=new File(rep); if (!repertoire.isDirectory()) System.exit(0); fichier=new File("fich.txt"); System.out.println("le fichier "+fichier.getName()+(fichier.exists()?" existe":" n'existe pas")); sortie=new BufferedWriter(new FileWriter("fich.txt")); sortie.write("bonjour"); sortie.close(); System.out.println("le fichier "+fichier.getName()+

(fichier.exists()?" existe":" n'existe pas")); System.out.println("Sa longueur est "+fichier.length()); System.out.println("Son chemin complet est \n "+fichier.getAbsolutePath());; System.out.println();

Page 56: 1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce

56

listeFichiers=repertoire.list(); for (int i=0;i < listeFichiers.length;i++) System.out.println(listeFichiers[i]); System.out.println(); nouveauFichier=new File("autre.essai"); fichier.renameTo(nouveauFichier); System.out.println("le fichier "+fichier.getName()+

(fichier.exists()?" existe":" n'existe plus")); System.out.println("le fichier

"+nouveauFichier.getName()+ (nouveauFichier.exists()?" existe":" n'existe pas"));

nouveauFichier.delete(); }}