1. Introducción
Al crear aplicaciones basadas en datos, a menudo es necesario capturar texto y datos binarios. Es posible que un programa de este tipo necesite almacenar imágenes, archivos PDF, archivos de Word u otros datos binarios. Hay dos formas de almacenar estos datos binarios: en el sistema de archivos del servidor web y agregando una referencia al archivo correspondiente en la base de datos o directamente en la propia base de datos.
Los datos textuales, como cadenas, números, fechas, GUID, valores monetarios, etc., tienen definiciones de tipos de datos apropiadas y correspondientes en el sistema de base de datos. Por ejemplo, en Microsoft SQL Server, puede usar el tipo de datos int para almacenar un valor entero y para almacenar un valor de cadena, puede usar un tipo varchar o nvarchar. Además, la base de datos también proporciona definiciones de tipos para almacenar datos binarios. En Microsoft SQL SERVER 2000 y versiones anteriores, el tipo de datos de imagen se usa para almacenar datos binarios; en SQL SERVER 2005, se usa el tipo de datos varbinary (MAX). Estos tipos de datos son capaces de almacenar datos binarios de hasta 2 GB de tamaño utilizando cualquiera de los dos métodos anteriores.
Sin embargo, cuando se almacenan datos binarios directamente en la base de datos, se requiere trabajo adicional para insertar, actualizar y recuperar los datos binarios. Afortunadamente, podemos abstraer esta compleja operación T-SQL de bajo nivel a través de bibliotecas de acceso a datos de nivel superior, como ADO.NET, de modo que el problema se vuelve bastante simple. Sin embargo, trabajar con datos binarios a través de ADO.NET es un poco diferente a trabajar con datos de texto. En este artículo, analizaremos cómo utilizar ADO.NET y el control SqlDataSource de ASP.NET 2.0 para almacenar y recuperar archivos de imágenes directamente desde una base de datos. ¡Sigue leyendo!
2. Comparación entre almacenar datos en la base de datos y almacenarlos en el sistema de archivos
Como se acaba de presentar, al capturar datos binarios en una aplicación, los datos binarios se pueden almacenar directamente en la base de datos o como un archivo en la web. sistema de archivos: solo se mantiene una referencia al archivo en la base de datos. En mi experiencia, he descubierto que la mayoría de los desarrolladores prefieren almacenar datos binarios en el sistema de archivos, principalmente por las siguientes razones:
· Se requiere menos esfuerzo: almacenar y recuperar archivos binarios almacenados en una base de datos requiere más esfuerzo de codificación. Además, actualizar estos datos binarios será más fácil: no es necesario comunicarse con la base de datos, ¡simplemente modifique el archivo directamente!
· Las URL que apuntan a archivos son más directas: como veremos en este artículo, para proporcionar acceso a datos binarios almacenados en una base de datos, necesitamos crear otra página ASP.NET que pueda devolver esos datos. Normalmente, a esta página se pasa un identificador único correspondiente al registro correspondiente en la base de datos (que devuelve sus datos binarios). El resultado es que para acceder a los datos binarios (por ejemplo, una imagen cargada) la URL se parece a http://www.yourserver.com/ShowImage.aspx?ID=4352 , mientras que si la imagen se almacenó directamente en el archivo In En el sistema, la URL será más directa, por ejemplo http://www.yourserver.com/UploadedImages/Sam.jpg.
· Mejor soporte de herramientas para mostrar imágenes: si está utilizando ASP.NET 2.0, puede usar un control ImageField en un control GridView o DetailsView para mostrar una imagen (su ruta de imagen se almacena en la base de datos). Sin embargo, desafortunadamente, este ImageField no puede mostrar directamente los datos de la imagen en la base de datos (ya que requiere consultar una página externa y devolver los datos correspondientes).
· Rendimiento: dado que los archivos binarios se almacenan en el sistema de archivos del servidor web en lugar de en la base de datos, la aplicación puede acceder a menos datos en la base de datos, lo que reduce los requisitos de la base de datos y, en consecuencia, reduce los requisitos de la web y la congestión de la red entre servidores de bases de datos.
La principal ventaja de almacenar datos directamente en la base de datos es que los hace "autocontenidos". Ahora que todos los datos están contenidos en la base de datos, el soporte de datos, el movimiento de datos entre servidores de bases de datos, la replicación de bases de datos, etc. son mucho más fáciles porque no hay necesidad de preocuparse por copiar o hacer copias de seguridad del contenido binario almacenado en el sistema de archivos.
Como siempre, la solución de almacenamiento a elegir dependerá del sitio de uso real y de las necesidades comerciales. Por ejemplo, desarrollé un cliente en el que los datos binarios debían almacenarse en una base de datos porque el software de informes que utilizaban solo podía incluir datos binarios en el informe, si procedían de la base de datos. En otro caso, un colega mío estaba trabajando en un proyecto en el que los binarios debían ser utilizados por una aplicación web y estar disponibles a través de FTP, en cuyo caso era necesario almacenar los datos binarios en el sistema de archivos.
3. Cree una tabla de base de datos para almacenar datos binarios
El resto de este artículo analizará una aplicación de galería de imágenes ASP.NET 2.0 simple que escribí usando Microsoft SQL Server 2005 Express Edition para demostrar los conceptos directos relacionados con el almacenamiento y la recuperación de datos binarios en un base de datos.
El modelo de datos de esta aplicación de galería de imágenes consta de una tabla - Imágenes, donde cada registro corresponde a una imagen de la galería. El campo MIMEType de esta tabla Imágenes almacena el tipo MIME de la imagen cargada (imagen/jpeg para archivos JPG, imagen/gif para archivos GIF, etc.), el tipo MIME aquí especifica al navegador cómo generar los datos binarios. La columna ImageData almacena el contenido binario real de la imagen.
4. Cargue una imagen y almacene datos binarios usando código ADO.NET.
Esta galería de imágenes permite a los visitantes cargar archivos de imágenes (formatos GIF, JPG y PNG) en esta aplicación. Una vez cargado, se agrega un nuevo registro a la tabla Imágenes y el contenido del archivo de imagen se almacena en la columna ImageData del nuevo registro. Para cargar archivos desde el navegador web al servidor web en ASP.NET 2.0, en este ejemplo se utiliza el control FileUpload. Usar el control FileUpload es muy simple: simplemente arrástrelo desde la barra de herramientas a su página. En última instancia, este control FileUpload se generará en el navegador del usuario como un formulario de carga de archivos estándar: un botón "Examinar" (cuando se hace clic) permite al usuario seleccionar un archivo de su disco duro para cargarlo en el servidor web.
Por ejemplo, para crear una interfaz para agregar una nueva imagen, utilicé un control TextBox para capturar el título de la imagen y un control FileUpload para permitir al usuario especificar la imagen a cargar:
<b>Título:</b>
<asp:TextBox ID="PictureTitle" runat="servidor" />
<br />
<b>Imagen:</b>
<asp:FileUpload ID="Archivo cargado" runat="servidor" />
<br />
<asp:LinkButton ID="btnInsert" runat="servidor" Text="Insertar" />
El código anterior crea una página donde el usuario puede especificar un archivo de su disco duro para cargarlo en el servidor web.
Una vez que el usuario selecciona un archivo y envía el formulario (por ejemplo, haciendo clic en el botón "Insertar"), el contenido binario del archivo especificado se envía al servidor web. Desde el código del lado del servidor, estos datos binarios están disponibles a través de la propiedad PostedFile.InputStream del control FileUpload, como lo demuestra el siguiente marcado y código:
Protected Sub btnInsert_Click(ByVal sender As Object, ByVal y As System.EventArgs) Handles btnInsert . Hacer clic
'Asegúrese de que un archivo se haya cargado correctamente
Si UploadedFile.PostedFile no es nada o si no String.IsNullOrEmpty(UploadedFile.PostedFile.FileName) o si no UploadedFile.PostedFile.InputStream no es nada, entonces
...muestra mensaje de error...
Salir Sub
Terminar si
'Asegúrate de que estamos trabajando con un archivo JPG o GIF
Extensión tenue As String = Path.GetExtension(UploadedFile.PostedFile.FileName).ToLower()
Dim MIMEType como cadena = nada
Seleccione la extensión del caso
Caso ".gif"
Tipo MIME = "imagen/gif"
Caso ".jpg", ".jpeg", ".jpe"
Tipo MIME = "imagen/jpeg"
Caso ".png"
Tipo MIME = "imagen/png"
Caso más
'Carga de tipo de archivo no válido... se muestra un mensaje de error...
Salir Sub
Fin Seleccione
'Conectarse a la base de datos e insertar un nuevo registro en la tabla Productos
Usando myConnection como nuevo SqlConnection(ConfigurationManager.ConnectionStrings("ImageGalleryConnectionString").ConnectionString)
Const SQL como cadena = "INSERT INTO [Imágenes] ([Título], [MIMEType], [ImageData]) VALORES (@Title, @MIMEType, @ Datos de imagen)"
Atenuar myCommand como nuevo SqlCommand (SQL, myConnection)
myCommand.Parameters.AddWithValue("@Title", PictureTitle.Text.Trim())
myCommand.Parameters.AddWithValue("@MIMEType", MIMEType)
'Carga el flujo de entrada del control FileUpload en una matriz de bytes
Atenuar imageBytes (UploadedFile.PostedFile.InputStream.Length) como byte
UploadedFile.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length)
myCommand.Parameters.AddWithValue("@ImageData", imageBytes)
miConexión.Open()
myCommand.ExecuteNonQuery()
miConexión.Cerrar()
Finalizar el uso
End
SubHere, este controlador de eventos primero garantiza que se haya cargado un archivo. Luego determina el tipo MIME según la extensión del archivo que se carga.
La parte más notable de lo anterior es la sección de código que establece los parámetros @ImageData. Primero, cree una matriz de bytes llamada imageBytes y haga que su longitud sea la correspondiente al flujo de entrada del archivo que se está cargando. Luego, use el método Read de InputStream para completar el contenido binario en esta matriz de bytes. Tenga en cuenta que es esta matriz de bytes la que se especifica como valor de @ImageData.