102 - Excepciones - bloque finally


El manejo de excepciones en C# puede incluir otro bloque llamado 'finally':

try {
  [instrucciones 1]
} catch([excepción 1]) {
  [instrucciones 2]
} finally {
  [instrucciones 3]
}

El objetivo de este bloque es liberar recursos que se solicitan en el bloque try. El bloque finally se ejecuta siempre, inclusive si se genera la captura de una excepción.

Los recursos más comunes que se deben liberar son las conexiones a bases de datos, uso de archivos y conexiones de red. Un recurso que no se libera impide que otro programa lo pueda utilizar. Al disponer la liberación de recursos en el bloque 'finally' nos aseguramos que todo recurso se liberará, inclusive aunque se dispare una excepción.

Tener en cuenta que si no se disparan ninguna excepción en un bloque try luego de esto se ejecuta el bloque 'finally'.

El bloque finally es opcional y en el caso de estar presente se coloca después del último bloque catch.

Problema:

Crear un archivo de texto con dos líneas. Luego proceder a leer el contenido del archivo de texto y mostrarlo por pantalla. Asegurarse de liberar el archivo luego de trabajar con el mismo

Programa:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PruebaExcepcion6
{
    class Program
    {
        static void Main(string[] args)
        {
            StreamWriter txt=null;
            try
            {
                txt = new StreamWriter("datos.txt");
                txt.WriteLine("Línea 1");
                txt.WriteLine("Línea 2");
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                if (txt!=null)
                    txt.Close();
            }

            StreamReader txtleer = null;
            try
            {
                txtleer = new StreamReader("datos.txt");
                string linea = txtleer.ReadLine();
                while (linea != null)
                {
                    Console.WriteLine(linea);
                    linea = txtleer.ReadLine();
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                if (txtleer != null)
                    txtleer.Close();
            }
            Console.ReadKey();
        }
    }
}

Hemos sacado del try la definición de las dos variables para la creación de archivos de texto:

            StreamWriter txt=null;
            ...
            StreamReader txtleer = null;

En el bloque try si hay un problema cuando se crea el archivo 'datos.txt' o cuando se graban datos mediante el método WriteLine se dispara la excepción IOException:

            try
            {
                txt = new StreamWriter("datos.txt");
                txt.WriteLine("Línea 1");
                txt.WriteLine("Línea 2");
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message);
            }

Luego que se haya disparado la excepción o no, pasa a ejecutarse el bloque 'finally', donde debemos llamar al método Close tanto del objeto txt como txtleer, como los objetos pueden no haberse creado, disponemos un if para cada uno:

            finally
            {
                if (txt!=null)
                    txt.Close();
            }

Las clases 'StreamReader' y 'StreamWriter' se encuentran declaradas en el espacio de nombres:

using System.IO;

Podemos comprobar que el bloque finally se ejecuta siempre indistintamente a que se genere una excepción ejecutando la aplicación en modo depuración presionando en forma sucesiva la tecla 'F10':

C# excepciones bloque finally

Retornar