2009-06-06 10 views
5

Tengo imágenes almacenadas en mi base de datos en FILESTREAM y estoy tratando de averiguar cuál es la mejor solución para que esa imagen vuelva a aparecer en un navegador web.¿Cuál es la forma más rápida de transmitir una imagen de FILESTREAM en SQL a un navegador?

Si yo era la gestión de los archivos del sistema de archivos a mí mismo, la forma más rápida simplemente sería:

Response.TransmitFile(pathToFile); 

Esto no quiere cargar el archivo en la memoria antes de transmitirlo al cliente (a mi entender) y como tal es lindo y rápido.

Actualmente estoy usando Linq a SQL para obtener el FILESTREAM. Esto proporciona el FILESTREAM como un objeto binario.

hasta ahora tienen esta forma bastante feo de hacerlo:

Response.WriteBinary(fileStreamBinary.ToArray()); 

voy a estar mejor sin molestarse con el LINQ to SQL y hacer las cosas de forma más directa?

Estoy empezando a preguntarme por qué me molesté con FILESTREAM en primer lugar y no me limité a administrar los archivos yo mismo. ¡Estoy seguro de que había una razón para ello sin usar la palabra "carro de la banda"!

Respuesta

1

Esto no carga el archivo en la memoria antes de transmitirla de nuevo a el cliente (a mi entender) y como tal es bueno y rápido.

Corrija, pero recuerde configurar Response.BufferOutput en falso, el valor predeterminado es verdadero.

¿Voy a estar mejor sin molestarme con el Linq a SQL y hacer las cosas más directamente?

Si no desea cargar primero todo el contenido binario en la memoria, entonces sí. Aquí está an example para la transmisión de datos binarios desde una base de datos (junto con la habilitación de la funcionalidad de descarga reanudable).

estoy empezando a preguntarse por qué me he molestado con FILESTREAM en el primer lugar y no sólo se adhieren a la gestión de los archivos de mi mismo

El beneficio principal es la integridad de datos con soporte transaccional y la inclusión en las copias de seguridad de la base de datos para que no tenga que preocuparse por la disparidad entre la copia de seguridad de la base de datos y la copia de seguridad del sistema de archivos. La desventaja siempre ha sido el rendimiento, que es lo que esta característica de toda la extensión de archivos está tratando de superar. Aunque si tienen un promedio inferior a 1mb según this document, en realidad se almacena más rápidamente en la base de datos que en el sistema de archivos.

En Sql Server 2012 hay una nueva característica denominada FileTables que se basa en el soporte de FileStream. Básicamente actúa como una vista de base de datos de un directorio de sistema de archivos porque los archivos añadidos a ese directorio se agregan automáticamente a la base de datos FileTable (es una tabla de esquema fija, que contiene una columna binaria Filestream para el archivo, que puede vincular desde otras tablas) Esto le permitiría recuperar una ruta al archivo que puede alimentar a su función Response.TransmitFile(...), y aún así beneficiarse del soporte de sql Filestream.

1

¿Qué tal eso?

byte[] buffer = new byte[bufferSize]; 
int nBytes; 
while((nBytes = fileStreamBinary.Read(buffer, 0, bufferSize) != 0) 
{ 
    Response.OutputStream.Write(buffer, 0, nBytes); 
} 

De esa manera nunca se cargue toda la corriente en la memoria

+0

Hmmm tal vez estamos hablando de diferentes tipos de objetos binarios - Linq devuelve un objeto System.Data.Linq.Binary que no tiene un método Read() :( – joshcomley

+0

Lo siento, no entendí la muestra de código y pensé que fileStreamBinary era un stream ... No estoy familiarizado con System.Data.Linq.Binary, pero parece que está buscando todo el búfer de una vez, por lo que no puede evitar cargarlo en la memoria. Así que me temo que el código que encuentra "feo" es la única forma ... –

+0

Parece que tendré que eludir a Linq cuando uso FILESTREAM en ese momento. Parece una tontería ya que el objetivo de FILESTREAM era permitir la transmisión directa súper rápida desde el disco! – joshcomley

0

Básicamente la misma idea que presentó Thomas, pero un poco más detallado. El almacenamiento en búfer debe desactivarse y los datos deben confirmarse/purgarse periódicamente para evitar almacenar en el búfer todos los datos entrantes antes de enviarlos al cliente.

estoy usando un código similar para transmitir datos (en este caso Pdf: s) y una gota en un base de datos ->WCF Servicio (streaming) ->cliente (Navegador)

Este probablemente no sea el mejor enfoque para artículos más pequeños, pero útil para transmitir cosas provenientes de algún tipo de transmisión.

Response.Clear(); 
Response.ContentType = "application/pdf"; 
Response.Buffer = false; 

var buffer = new byte[BufferSize]; 
int bytesRead; 
while ((bytesRead = inputStream.Read(buffer, 0, BufferSize)) != 0) 
{ 
    if (!Response.IsClientConnected) 
      break; 

    Response.OutputStream.Write(buffer, 0, bytesRead); 
    Response.Flush(); 
} 
Cuestiones relacionadas