next up previous contents index
Next: Définitions de types Up: Quelques éléments de Caml Previous: Entrées - Sorties

Copie de fichiers

Le traitement des fichiers nous permet d'illustrer le mécanisme d'exception. Par exemple, l'ouverture d'un fichier inexistant se solde par le déclenchement d'une erreur par le système d'exploitation: l'exception sys__Sys_error est lancée avec pour argument la chaîne de caractères "fichier: No such file or directory".

#open_in "essai";;
Exception non rattrapée: sys__Sys_error "essai: No such file or directory"

On remarque qu'une exception qui n'est pas rattrapée interrompt complètement les calculs.

Supposons maintenant que le fichier de nom essai existe. Après avoir ouvert un canal sur ce fichier et l'avoir lu entièrement, toute tentative de lecture provoque aussi le déclenchement d'une exception, l'exception prédéfinie End_of_file:

 

#let ic = open_in "essai" in
  while true do input_line ic done;;
Exception non rattrapée: End_of_file

À l'aide d'une construction try, on récupèrerait facilement l'erreur pour l'imprimer (et éventuellement continuer autrement le programme). Nous illustrons ce mécanisme en écrivant une procédure qui copie un fichier dans un autre. On utilise une boucle infinie qui copie ligne à ligne le canal d'entrée et ne s'arrête que lorsqu'on atteint la fin du fichier à copier, qu'on détecte par le déclenchement de l'exception prédéfinie End_of_file. Ici le déclenchement de l'exception n'est pas une erreur, c'est au contraire l'indication attendue de la fin du traitement.

#open "printf";;

let copie_channels ic oc =
 try
  while true do
   let line = input_line ic in
   output_string oc line;
   output_char oc `\n` 
  done
 with
 | End_of_file -> close_in ic; close_out oc;;

La procédure de copie elle-même se contente de créer les canaux sur les fichiers d'entrée et de sortie, puis d'appeler la procédure copie_channels. Comme les ouvertures des fichiers d'entrée et de sortie sont susceptibles d'échouer, la procédure utilise deux try imbriqués pour assurer la bonne gestion des erreurs. En particulier, le canal d'entrée n'est pas laissé ouvert quand il y a impossibilité d'ouvrir le canal de sortie. Dans le try intérieur qui protège l'ouverture du fichier de sortie et la copie, on remarque le traitement de deux exceptions. La deuxième, sys__Break, est déclenchée quand on interrompt le programme. En ce cas un message est émis, les canaux sont fermés et l'on déclenche à nouveau l'interruption pour prévenir la fonction appelante que la copie ne s'est pas déroulé normalement.

let copie origine copie =
 try
  let ic = open_in origine in
   try
    let oc = open_out copie in
    copie_channels ic oc
   with
   | sys__Sys_error s ->
      close_in ic;
      printf "Impossible d'ouvrir le ficher %s \n" copie;
      raise (sys__Sys_error s)
   | sys__Break ->
      close_in ic;
      close_out oc;
      printf "Interruption pendant la copie de %s dans %s\n" origine copie;
      raise (sys__Break)  
 with
 | sys__Sys_error s ->
    printf "Le ficher %s n'existe pas\n" origine;
    raise (sys__Sys_error s);;


next up previous contents index
Next: Définitions de types Up: Quelques éléments de Caml Previous: Entrées - Sorties

1/11/1998