Introducción a C#
Por Nacho Cabanes, versión 0.93 de 16-abr-2010


(Nota: Estás viendo una versión del curso antigua, creada en 2009. Es recomendable que sigas la versión 2015, mucho más actualizada, con contenidos más detallados, más ejemplos y más ejercicios propuestos)

7.8. Conceptos básicos sobre ficheros

Llega el momento de ver algunos conceptos que hemos pasado por encima, y que es necesario conocer:

7.9. Leer datos básicos de un fichero binario

Los ficheros de texto son habituales, pero es aún más frecuente encontrarnos con ficheros en los que la información está estructurada como una secuencia de bytes, más o menos ordenada. Esto ocurre en las imágenes, los ficheros de sonido, de video, etc.

Vamos a ver cómo leer de un fichero "general", y lo aplicaremos a descifrar la información almacenada en ciertos formatos habituales, como una imagen BMP o un sonido MP3.

Como primer acercamiento, vamos a ver cómo abrir un fichero (no necesariamente de texto) y leer el primer byte que contiene. Usaremos una clase específicamente diseñada para leer datos de los tipos básicos existentes en C# (byte, int, float, etc.), la clase "BinaryReader":

/*---------------------------*/
/*  Ejemplo en C# nº 77:     */
/*  ejemplo77.cs             */
/*                           */
/*  Ficheros binarios (1)    */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
using System.IO;
 
public class Ejemplo77
{
 
  public static void Main()
  {
    BinaryReader fichero;
    string nombre;
    byte unDato;
 
    Console.WriteLine("Introduzca el nombre del fichero");
    nombre = Console.ReadLine();
 
    try 
    {
      fichero = new BinaryReader(
        File.Open(nombre, FileMode.Open));
      unDato = fichero.ReadByte();
      Console.WriteLine("El byte leido es un {0}",
        unDato);
      fichero.Close();    
    } 
    catch (Exception exp)
    {
      Console.WriteLine(exp.Message);
      return;
    }
  }
 
}
 

La forma de abrir un BinaryReader es algo más incómoda que con los ficheros de texto, porque nos obliga a llamar a un constructor y a indicarle ciertas opciones sobre el modo de fichero (la habitual será simplemente "abrirlo", con "FileMode.Open"), pero a cambio podemos leer cualquier tipo de dato, no sólo texto: ReadByte lee un dato "byte", ReadInt32 lee un "int", ReadSingle lee un "float", ReadString lee un "string", etc.

Ejercicios propuestos:

7.10. Leer bloques de datos de un fichero binario

Leer byte a byte (o float a float) puede ser cómodo, pero también es lento. Por eso, en la práctica es más habitual leer grandes bloques de datos. Típicamente, esos datos se guardarán como un array de bytes.

Para eso, usaremos la clase "FileStream", más genérica. Esta clase tiene método "Read", que nos permite leer una cierta cantidad de datos desde el fichero. Le indicaremos en qué array guardar esos datos, a partir de qué posición del array debe introducir los datos, y qué cantidad de datos se deben leer. Nos devuelve un valor, que es la cantidad de datos que se han podido leer realmente (porque puede ser menos de lo que le hemos pedido, si hay un error o estamos al final del fichero).

Para abrir el fichero usaremos "OpenRead", como en este ejemplo:

/*---------------------------*/
/*  Ejemplo en C# nº 78:     */
/*  ejemplo78.cs             */
/*                           */
/*  Ficheros binarios (2)    */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
using System.IO;
 
public class Ejemplo78
{
 
  public static void Main()
  {
    FileStream fichero;
    string nombre;
    byte[] datos;
    int cantidadLeida;
 
    Console.WriteLine("Introduzca el nombre del fichero");
    nombre = Console.ReadLine();
 
    try 
    {
      fichero = File.OpenRead(nombre);
      datos = new byte[10];
      int posicion = 0;
      int cantidadALeer = 10;
      cantidadLeida = fichero.Read(datos, posicion, cantidadALeer);
 
      if (cantidadLeida < 10)
        Console.WriteLine("No se han podido leer todos los datos!");
      else {
        Console.WriteLine("El primer byte leido es {0}", datos[0]);
        Console.WriteLine("El tercero es {0}", datos[2]);
      }
 
      fichero.Close();    
    } 
    catch (Exception exp)
    {
      Console.WriteLine(exp.Message);
      return;
    }
  }
 
}
 

Ejercicios propuestos: