Какой самый быстрый способ передать изображение из FILESTREAM в SQL в браузер? - PullRequest
5 голосов
/ 06 июня 2009

У меня есть изображения, хранящиеся в моей базе данных в FILESTREAM, и я пытаюсь выяснить, как лучше всего вернуть это изображение в веб-браузер.

Если бы я сам управлял файлами в файловой системе, самый быстрый способ был бы просто:

Response.TransmitFile(pathToFile);

Это не загружает файл в память перед его передачей обратно клиенту (насколько я понимаю), и, таким образом, это приятно и быстро.

В настоящее время я использую Linq to SQL для получения FILESTREAM. Это обеспечивает FILESTREAM как двоичный объект.

Пока что есть такой ужасный способ сделать это:

Response.WriteBinary(fileStreamBinary.ToArray());

Будет ли мне лучше не беспокоиться о Linq to SQL и делать что-то более прямое?

Я начинаю задумываться, почему я в первую очередь беспокоился о FILESTREAM, а не просто сам управлял файлами. Я уверен, что была причина для этого без использования слова «победа»!

Ответы [ 3 ]

1 голос
/ 02 февраля 2012

Это не загружает файл в память перед его передачей обратно клиент (насколько я понимаю) и как таковой хорош и быстр.

Исправьте, но не забудьте установить для Response.BufferOutput значение false, по умолчанию установлено значение true.

Будет ли мне лучше не беспокоиться о Linq to SQL и делать что-то более прямое?

Если вы не хотите сначала загружать весь двоичный контент в память, тогда да. Вот пример для потоковой передачи двоичных данных из базы данных (наряду с включением функции возобновляемой загрузки).

Я начинаю задумываться, почему я беспокоился о FILESTREAM в первом место, а не просто управлять файлами самостоятельно

Основным преимуществом является целостность данных с поддержкой транзакций и включением в резервные копии базы данных, поэтому вам не нужно беспокоиться о несоответствии между резервным копированием базы данных и резервным копированием файловой системы. Недостатком всегда была производительность, которую пытается преодолеть вся эта функция файлового потока. Хотя, согласно в среднем они меньше 1 МБ, этот документ на самом деле быстрее сохраняется в базе данных, чем в файловой системе.

В Sql Server 2012 появилась новая функция под названием FileTables , основанная на поддержке FileStream. По сути, он действует как представление базы данных каталога файловой системы, в котором файлы, добавленные в этот каталог, автоматически добавляются в базу данных FileTable (это таблица фиксированной схемы, которая содержит двоичный столбец Filestream для файла, на который вы можете ссылаться из других таблиц ). Это позволит вам затем получить путь к файлу, который вы можете передать своей функции Response.TransmitFile(...), но при этом по-прежнему пользоваться поддержкой sql Filestream.

1 голос
/ 06 июня 2009

Как насчет этого?

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

Таким образом, вы никогда не загрузите весь поток в память

0 голосов
/ 14 апреля 2011

В основном та же идея, что и Томас, но немного более многословно. Буферизацию следует отключить, а данные периодически фиксировать / сбрасывать, чтобы избежать буферизации всех входящих данных перед их отправкой клиенту.

Я использую аналогичный код для потоковой передачи данных (в данном случае Pdf: s) из BLOB-объекта в База данных -> Служба WCF (потоковая передача) -> Клиент (Браузер)

Вероятно, это не лучший подход для небольших объектов, но он полезен для передачи данных, поступающих из какого-то потока.

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();
}
...