Next: Définitions de types
Up: Quelques éléments de Caml
Previous: Entrées - Sorties
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);;
1/11/1998