El uso de "File.Exists" nos permite saber si el fichero existe, pero ese no es el único problema que podemos tener al acceder a un fichero. Puede ocurrir que no tengamos permiso para acceder al fichero, a pesar de que exista, o que intentemos escribir en un dispositivo que sea sólo de lectura (como un CD-ROM, por ejemplo).
Por ello, una forma más eficaz de comprobar si ha existido algún tipo de error es comprobar las posibles "excepciones", con las que ya tuvimos un contacto al final del tema 2.
Típicamente, los pasos que puedan ser problemáticos irán dentro del bloque "try" y los mensajes de error y/o acciones correctoras estarán en el bloque "catch". Así, un primer ejemplo, que mostrara todo el contenido de un fichero de texto y que en caso de error se limitara a mostrar un mensaje de error y a abandonar el programa, podría ser:
// Ejemplo_08_07a.cs
// Excepciones y ficheros (1)
// Introducción a C#, por Nacho Cabanes
using System;
using System.IO;
public class Ejemplo_08_07a
{
public static void Main()
{
StreamReader fichero;
string nombre;
string linea;
Console.WriteLine("Introduzca el nombre del fichero");
nombre = Console.ReadLine();
try
{
fichero = File.OpenText(nombre);
do
{
linea = fichero.ReadLine();
if (linea != null)
Console.WriteLine( linea );
}
while (linea != null);
fichero.Close();
}
catch (Exception exp)
{
Console.WriteLine("Ha habido un error: {0}", exp.Message);
return;
}
}
}
El resultado, si ese fichero no existe, sería algo como
Introduzca el nombre del fichero
prueba
Ha habido un error: No se pudo encontrar el archivo 'C:\Fuentes
acho\prueba'.
Pero, como ya vimos, generalmente lo razonable no es interceptar "todas las excepciones a la vez", sino crear un análisis para cada caso, que permita recuperarse del error y seguir adelante, para lo que se suelen crear varios bloques "catch". Por ejemplo, en el caso de que queramos crear un fichero, podemos tener excepciones como éstas:
Así, dentro de cada bloque "catch" podríamos indicar una excepción más concreta que una simple "Exception", de forma que el mensaje de aviso sea más concreto, o que podamos dar pasos más adecuados para solucionar el problema:
// Ejemplo_08_07b.cs
// Excepciones y ficheros (2)
// Introducción a C#, por Nacho Cabanes
using System;
using System.IO;
public class Ejemplo_08_07b
{
public static void Main()
{
StreamWriter fichero;
string nombre;
string linea;
Console.Write("Introduzca el nombre del fichero: ");
nombre = Console.ReadLine();
Console.Write("Introduzca la frase a guardar: ");
linea = Console.ReadLine();
try
{
fichero = File.CreateText(nombre);
fichero.WriteLine( linea );
fichero.Close();
}
catch (PathTooLongException e)
{
Console.WriteLine("Nombre demasiado largo!");
}
catch (IOException e)
{
Console.WriteLine("No se ha podido escribir!");
Console.WriteLine("El error exacto es: {0}", e.Message);
}
}
}
Las excepciones más generales (IOException y, sobre todo, Exception) deberán ser las últimas que analicemos, y las más específicas deberán ser las primeras.
Hay que recordar que, como la consola se comporta como un fichero de texto (realmente, como un fichero de entrada y otro de salida), se puede usar "try…catch" para comprobar ciertos errores relacionados con la entrada de datos, como cuando no se puede convertir un dato a un cierto tipo (por ejemplo, si queremos esperamos que introduzca un número, pero, en lugar de ello, tecleado un texto).
Ejercicios propuestos:
Ejercicio propuesto 8.7.1: Un programa que pida al usuario el nombre de un fichero de origen y el de un fichero de destino, y que vuelque al segundo fichero el contenido del primero, convertido a mayúsculas. Se debe controlar los posibles errores, como que el fichero de origen no exista, o que el fichero de destino no se pueda crear.
Ejercicio propuesto 8.7.2: Un programa que pida al usuario un número, una operación (+, -, *, /) y un segundo número, y muestre el resultado de la correspondiente operación. Si se teclea un dato no numérico, el programa deberá mostrar un aviso y volver a pedirlo, en vez de interrumpir la ejecución.
Ejercicio propuesto 8.7.3: Un programa que pida al usuario repetidamente pares de números y la operación a realizar con ellos (+, -, *, /) y guarde en un fichero "calculadora.txt" el resultado de dichos cálculos (con la forma "15 * 6 = 90"). Debe controlar los posibles errores, como que los datos no sean numéricos, la división entre cero, o que el fichero no se haya podido crear.