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 fichero de sonido MP3.
Como primer acercamiento, vamos a ver cómo abrir un fichero (no necesariamente de texto) y leer el primer byte que contiene. Comenzaremos por utilizar la clase FileStream, diseñada para acceder a un byte o a bloques de bytes. Esta clase tiene un método ReadByte, que devuelve un entero con valor -1 en caso de error, o un dato que podríamos convertir a byte si la lectura ha sido correcta, así:
// Ejemplo_08_09a.cs
// Ficheros binarios: lectura de un byte con FileStream
// Introducción a C#, por Nacho Cabanes
using System;
using System.IO;
public class Ejemplo_08_09a
{
public static void Main()
{
FileStream fichero;
string nombre;
byte unDato;
Console.WriteLine("Introduzca el nombre del fichero");
nombre = Console.ReadLine();
try
{
fichero = File.OpenRead(nombre);
unDato = (byte) fichero.ReadByte();
Console.WriteLine("El byte leido es un {0}",
unDato);
fichero.Close();
}
catch (Exception e)
{
Console.WriteLine("Error: "+e.Message);
return;
}
}
}
Podemos usar también un constructor para acceder al fichero. Este constructor recibirá dos parámetros: el nombre del fichero y el modo de apertura. Por ahora, nos interesará un único modo, que será "FileMode.Open", que nos permite leer datos desde un fichero que ya existe:
// Ejemplo_08_09b.cs
// Ficheros binarios: lectura de un byte con FileStream, constructor
// Introducción a C#, por Nacho Cabanes
using System;
using System.IO;
public class Ejemplo_08_09b
{
public static void Main()
{
Console.WriteLine("Introduzca el nombre del fichero");
string nombre = Console.ReadLine();
try
{
FileStream fichero = new FileStream(nombre, FileMode.Open);
byte unDato = (byte) fichero.ReadByte();
Console.WriteLine("El byte leido es un {0}",
unDato);
fichero.Close();
}
catch (Exception e)
{
Console.WriteLine("Error: "+e.Message);
return;
}
}
}
Y también podemos emplear la sintaxis alternativa, con "using", de modo que no sea necesario cerrar el fichero de forma explícita:
// Ejemplo_08_09c.cs
// Ficheros binarios: lectura de un byte con FileStream, using
// Introducción a C#, por Nacho Cabanes
using System;
using System.IO;
public class Ejemplo_08_09c
{
public static void Main()
{
Console.WriteLine("Introduzca el nombre del fichero");
string nombre = Console.ReadLine();
try
{
using (FileStream fichero = new FileStream(
nombre, FileMode.Open))
{
byte unDato = (byte) fichero.ReadByte();
Console.WriteLine("El byte leido es un {0}",
unDato);
}
}
catch (Exception e)
{
Console.WriteLine("Error: "+e.Message);
return;
}
}
}
Los otros modos de apertura posibles (cuyos nombre en inglés son casi autoexplicativos) son: Append (añade al final o crea si no existe), Create (crea el fichero o lo sobreescribe si ya existía), CreateNew (crea si no existía, o falla si existe), Open (abre si existe o falla si no existe), OpenOrCreate (abre si existe o lo crea si no existe), Truncate (abre un fichero que debe existir y lo vacía).
Si quisiéramos leer un segundo dato, volveríamos a llamar a ReadByte, porque tras cada lectura, avanza la posición actual dentro del fichero.
Ejercicios propuestos:
Ejercicio propuesto 8.9.1: Abre un fichero con extensión EXE (cuyo nombre introducirá el usuario) y comprueba si realmente se trata de un ejecutable, mirando si los dos primeros bytes del fichero son un 77 (que corresponde a una letra "M", según el estándar que marca el código ASCII) y un 90 (una letra "Z"), respectivamente.
Ejercicio propuesto 8.9.2: Abre una imagen BMP (cuyo nombre introducirá el usuario) y comprueba si realmente se trata de un fichero en ese formato, mirando si los dos primeros bytes del fichero corresponden a una letra "B" y una letra "M", respectivamente.
Ejercicio propuesto 8.9.3: Abre una imagen GIF y comprueba si sus tres primeros bytes son las letras G, I, F.