2009-06-06 13 views
5

私は自分のデータベースにFILESTREAMの画像を保存しています。その画像をWebブラウザに戻すのに最適な解決策を見つけようとしています。FILESTREAMからSQLでブラウザに画像をストリーミングする最も簡単な方法は何ですか?

私は、ファイルシステム上のファイルを管理していた場合は、自分自身、最も簡単な方法は、単に次のようになります。

Response.TransmitFile(pathToFile); 

これは、(私の理解に)、それをクライアントに戻って送信する前にメモリにファイルをロードしません。そのように素敵でスピーディーです。

私は現在、FILESTREAMを取得するためにLinq to SQLを使用しています。これは、FILESTREAMをバイナリオブジェクトとして提供します。

これまでのところ、それをすることのこの非常に醜い方法を持っている:

Response.WriteBinary(fileStreamBinary.ToArray()); 

私は、LINQ to SQLはで悩まとより直接的に物事をやっていないほうが良いとしているだろうか?

なぜ私はFILESTREAMを最初に気にかけていたのだろうと思っていて、ファイルの管理に固執していませんでした。私は「バンドワゴン」という言葉を使わずに理由があったと確信しています!

答えて

1

これは (私の理解への)クライアントに戻ってそれを送信する前にメモリにファイルをロードしない、そのように素敵でスピーディーです。

正しいですが、Response.BufferOutputを偽に設定することを忘れないでください。デフォルト値はtrueです。

私はLinq to SQLを気にしなくても、より直接的に作業する方が良いでしょうか?

バイナリコンテンツ全体を最初にメモリにロードしたくない場合は、はい。ここでは、データベースからバイナリデータをストリーミングする(再開可能なダウンロード機能を有効にする)ためのan exampleがあります。私は私が最初 場所でFILESTREAMに煩わさなぜ疑問に思い始めているだけのファイルを管理するに固執しませんでした

は自分自身

主な利点は、トランザクションのサポートと含めて、データの整合性でありますデータベースバックアップでは、データベースバックアップとファイルシステムバックアップの相違について心配する必要はありません。欠点は常にパフォーマンスです。これは、この全体のファイルストリーム機能が克服しようとしていることです。 this documentによると平均で1MB未満であれば、実際にはファイルシステムよりデータベースに格納されている方が高速です。

Sql Server 2012には、FileStreamサポートを基盤とするFileTablesという新機能があります。基本的には、そのディレクトリに追加されたファイルがデータベースに自動的に追加されるという点で、ファイルシステムディレクトリのデータベースビューのように動作します。FileTable(ファイルのFilestreamバイナリカラムを含む固定スキーマテーブルです。 )。これにより、Response.TransmitFile(...)関数に供給できるファイルへのパスを取得できますが、sql Filestreamのサポートの恩恵を受けます。

1

どうしますか?

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

あなたはメモリ

+0

多分私たちは別のバイナリオブジェクト型について話しているかもしれません - LinqはRead()メソッドを持たないSystem.Data.Linq.Binaryオブジェクトを返します:( – joshcomley

+0

あなたのコードサンプルを誤解し、fileStreamBinaryがストリーム...私はSystem.Data.Linq.Binaryに精通していませんが、バッファ全体を一度にフェッチしているようですので、メモリにロードすることは避けられません。 "醜い"唯一の方法です... –

+0

FILESTREAMを使用するとき、私はLinqを回避する必要があるかもしれないように見えます。FILESTREAMの全体の点として見てばかばかしいように見えるのは、超高速ダイレクトディスクからのストリーミングを許可することでした! – joshcomley

0

にトーマスが提示ますが、もう少し詳細なと基本的に同じ考えを全体ストリームをロードしませんこの方法。 クライアントに送信する前に、すべての受信データをバッファリングしないように、バッファリングをオフにしてデータを定期的にコミット/フラッシュします。

私は(この場合はPDFで:秒)のデータをストリーミングするために同様のコードを使用しています

データベースの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(); 
} 
関連する問題