ASP.Net WebApiを使用し、次のコードを使用してバイトをクライアントにストリーミングして、大きな画像ファイルを返そうとしています。
public class RetrieveAssetController : ApiController
{
// GET api/retrieveasset/5
public HttpResponseMessage GetAsset(int id)
{
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
string filePath = "SomeImageFile.jpg";
MemoryStream memoryStream = new MemoryStream();
FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
memoryStream.Write(bytes, 0, (int)file.Length);
file.Close();
httpResponseMessage.Content = new ByteArrayContent(memoryStream.ToArray());
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
httpResponseMessage.StatusCode = HttpStatusCode.OK;
return httpResponseMessage;
}
}
上記のコードは正常に機能しますが、処理するファイルの一部は2 GB以上のサイズであり、接続タイムアウトが発生する可能性があります。過去に(HttpHandlersを使用して)以下のようなコードを使用して、応答ストリームへの応答をチャンク化し、接続を正常に維持しました。
byte[] b = new byte[this.BufferChunkSize];
int byteCountRead = 0;
while ((byteCountRead = stream.Read(b, 0, b.Length)) > 0)
{
if (!response.IsClientConnected) break;
response.OutputStream.Write(b, 0, byteCountRead);
response.Flush();
}
前に示した新しいWebAPIプログラミングモデルを使用して、同様の手法をどのように使用できますか?
はい、PushStreamContent
を使用できます。また、非同期実行(つまり、非同期ラムダを使用)と組み合わせると、さらに効果的な結果が得られる可能性があります。
私は今月初めにこのアプローチについてブログを書きました http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/ 。
この例ではビデオファイルを使用しましたが、原則は同じです。つまり、データのバイトをクライアントにプッシュダウンします。
StreamContent
を使用してファイルから直接ストリーミングします(新しすぎますか?)。と同様 Web APIコントローラーはMemoryStreamをStreamContentに変換します
httpResponseMessage.Content = new StreamContent(file);