Écrire dans un fichier binaire                        

Écrire dans un fichier binaire

     

Un fichier binaire n'est pas prévu pour être lu avec un éditeur de texte, contrairement à un fichier de type texte. Dans un fichier binaire, il se peut que l'on décide d'écrire un int sous sa forme binaire ; alors le nombre 765 par exemple est codé par la suite de bits :
00000000 00000000 00000010 11111101 sur 4 octets,
ce qui donne «♦♦♦ý» sur l'imprimante utilisée pour imprimer ce livre ; dans un fichier texte utilisant le code ASCII (pour lequel le caractère '7' vaut 55 = 32 + 16 + 4 + 2 + 1, le caractère '6' vaut 54 et le caractère '5' vaut 53), la chaîne de caractères 765 est codé par la suite de bits :
00110111 00110110 00110101,
et apparaît avec un éditeur de texte ordinaire sous la forme de "765" (ce qui est nettement plus lisible...).

La classe FileOutputStrea est une classe d'extraction qui permet de construire un flux d'octets du programme vers un fichier. La classe DataOutputStream possède un constructeur qui reçoit en argument une instance de la classe OutputStream ; c'est une classe de fonctionnalités qui permet de transformer les données du programme en tableaux d'octets avant de mettre ceux-ci dans le flux.

Dans le programme ci-dessous, on aurait pu initialiser la variable sortie par :
    sortie = new DataOutputStream(new FileOutputStream(arg[0]));
si on utilise en plus, comme il est fait dans le programme, une instance de BufferedOutputStream, les écritures dans le fichier utilisent une mémoire tampon, ce qui rend l'exécution du programme plus efficace. La classe DataOutputStream dispose de beaucoup de méthodes ; nous illustrons les principales d'entre elles. La méthode size de cette classe indique le nombre d'octets traités par le flux concerné.

La méthode writeUTF(String s) nécessite quelques explications ; cette méthode permet de coder la chaîne de caractères indiquée selon le codage « UTF-8 modifié » dont le principe est fondé sur l'utilisation de code de longueurs variables. Rappelons que Java code les variables de type char sur deux octets, permettant ainsi un jeu de caractères étendu (cela étant devenu insuffisant, certains caractères rares sont codés avec deux variables de type char). Ce codage présente l'inconvénient d'être peu compact. Dans le codage UTF-8 modifié, les caractères Unicode de valeurs (en décimal) comprises entre 1 et 127 sont codés sur un octet, le bit de poids fort étant 0 ; les caractères du code ASCII sont donc codés sur un seul octet ; du 128e au 2047e, ils sont codés sur deux octets (sous la forme 110xxxxx 10xxxxxx, avec donc 11 bits disponibles ; le caractère de valeur 0 est aussi codé sur deux octets selon ce format, de telle sorte qu'aucun octet ne soit constitué que de 0) ; les suivants sont codés sur 3 octets (sous la forme 1110xxxx 10xxxxxx 10xxxxxx, avec donc 16 bits disponibles) ; ce système permet, lorsqu'on se place au début d'un octet d'un flux de caractères UTF-8 modifié, de déterminer le début du codage du caractère auquel on a accès. La méthode writeUTF(String s) code d'abord, sur deux octets, le nombre de caractères de s puis la chaîne de caractères en la codant en UTF-8 modifié.

On aurait pû initialiser notre variable ecrivain par :
    DataOutputStream(new FileOutputStream(argv[0]));
Cela aurait été identique en apparence, mais si on compose comme il est fait ici avec une instance de BufferedOutputStream, les écritures dans le fichier utilisent une mémoire-tampon, ce qui gagne du temps.

La classe OutputStream dispose de beaucoup de méthodes ; nous donnons des exemples ci-dessous des principales méthodes.

Voici le programme que nous proposons.

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

class EcrireFichierBinaire
{
  public static void main(String[] argv) throws IOException
  {
    DataOutputStream ecrivain;
    
    ecrivain =  
      new DataOutputStream(new BufferedOutputStream
			   (new FileOutputStream(argv[0])));

    ecrivain.writeUTF("bonjour");
    ecrivain.writeInt(3);
    ecrivain.writeLong(100000);
    ecrivain.writeFloat((float)2.35);
    ecrivain.writeDouble(3.5);
    ecrivain.writeChar('a');
    ecrivain.writeBoolean(false); 
    ecrivain.writeUTF("au revoir");
    System.out.println(ecrivain.size());
    ecrivain.close();
  }
} 
Après l'exécution de la commande
java EcrireFichierBinaire essai
on obtient à lécran : 47 et le fichier essai est assez illisible.

Vous pouvez récupérer ce programme.


© Irène Charon, Télécom ParisTech 2011