Mon
Apr
03
2006
Si hace unos días hablábamos de cómo
guardar ficheros binarios en SQL Server, hoy le toca a Microsoft Access. El proceso es similar, aunque para este ejemplo he decidido usar imágenes como los datos binarios que vamos a guardar y recuperar de la base de datos.
Imaginemos que tenemos una sencilla base de datos Access, con una única tabla llamada
Images, que tiene la siguiente estructura:
| Nombre |
Tipo |
| imgID |
int (Clave autonumérica) |
| FileName |
Texto(255) |
| ImageData |
Objeto OLE |
El campo
imgID almacenará una clave única autonumérica para identificar a cada registro.
FileName contendrá el nombre del fichero de imagen, e
ImageData contendrá
la imagen propiamente dicha, en formato binario.
El procedimiento para insertar imágenes en la base de datos Access es como sigue:
private void SaveData(string fileName)
{
try
{
//Creamos un nuevo FileStream a partir del fichero parámetro
//
//We create a new FileStream from the file specified as parameter
FileStream fs = new FileStream(fileName, FileMode.Open);
//Declaramos un array de bytes del tamaño del FileStream
//
//We declare a new byte array as big as the FileStream
Byte[] data = new byte[fs.Length];
//E introducimos los datos del FileStream en el array
//
//And we enter the data from the FileStream into the array
fs.Read(data, 0, Convert.ToInt32(fs.Length));
fs.Close();
//Creamos un nuevo DataAdapter, DataSet, CommandBuilder and DataRow
//para insertar el nuevo registro
//
//We create a new DataAdapter, DataSet, CommandBuilder and DataRow
//to perform the insertion of the new record
if(conn.State != ConnectionState.Open ) conn.Open();
OleDbDataAdapter adap =
new OleDbDataAdapter("SELECT * FROM Images", conn);
adap.MissingSchemaAction = MissingSchemaAction.AddWithKey;
OleDbCommandBuilder cmdBuilder = new OleDbCommandBuilder(adap);
adap.InsertCommand = cmdBuilder.GetInsertCommand();
DataSet ds = new DataSet();
adap.Fill(ds);
DataRow dr = ds.Tables[0].NewRow();
dr["FileName"] = fileName;
dr["ImageData"] = data; //The byte array
ds.Tables[0].Rows.Add(dr);
adap.Update(ds);
conn.Close();
//Esta funcion refresca un ListBox para que se refleje
//el nuevo registro insertado
//
//This function refreshes a ListBox to show the newly inserted record
LoadData();
MessageBox.Show("Done!\nImage file: " + fileName +
" added to the database.");
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Colorized by: CarlosAg.CodeColorizer Y los procedimientos que extrae las imágenes de la base de datos es tal que así:
/// <summary>
/// Coloca en el control Image la imagen recuperada de base de
/// datos por la función LoadImage, en base al índice único de
/// la imagen en la base de datos.
///
/// Sets in the Image control an image recovered from the database
/// via the LoadImage function, thanks to the unique identifier
/// of the image on the database.
/// </summary>
/// <param name="imgIndex">El identificador único de la imagen
///en la base de datos</param>
/// <param name="imgIndex">The unique identifier of the image
///on the database</param>
private void LoadImageControl(string imgIndex)
{
try
{
//Creamos un nuevo stream de memoria con el resultado
//de la función LoadImage, que devuelve un array de bytes
//
//We create a new MemoryStream with a byte array,
//returned by the LoadImage function
MemoryStream mem = new MemoryStream(LoadImage(imgIndex));
//Y establecemos que la imagen del control picImage es una nueva imagen,
//a partir del stream en memoria mem
//
//And we set the picImage control's image is a new image,
//built from the memory stream mem
picImage.Image = Image.FromStream(mem);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
/// <summary>
/// Carga la imagen de la base de datos en un array
//de bytes y devuelve dicho array
///
/// Loads the image from the database to a byte array and returns that array
/// </summary>
/// <param name="imgIndex">El ID unico de la imagen</param>
/// <param name="imgIndex">The unique ID of the image</param>
/// <returns>Devuelve la imagen en un array de bytes</returns>
/// <returns>The image on a byte array</returns>
private byte[] LoadImage(string imgIndex)
{
if(conn.State != ConnectionState.Open ) conn.Open();
sSQL = "SELECT ImageData FROM Images WHERE imgID = " + imgIndex;
OleDbCommand cmd = new OleDbCommand(sSQL, conn);
byte[] imgData = (byte[]) cmd.ExecuteScalar();
conn.Close();
return imgData;
}
Colorized by: CarlosAg.CodeColorizer En cualquier caso, tenéis disponible
aquí el código fuente completo, con comentarios en inglés y en español para esta aplicación. Descargadlo y jugad un poco con él.
NOTA.- Más adelante publicaré la forma de compactar y reparar mediante código C# una base de datos Microsoft Access. Aplicaciones como el código fuente que tenéis para descargar lo necesitan, y mucho.