17

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 プログラミング モデルを使用して、同様の手法を使用するにはどうすればよいでしょうか?

4

2 に答える 2

26

はい、使用できますPushStreamContent。また、非同期実行(つまり、非同期ラムダを使用)と組み合わせると、さらに効果的な結果が得られる可能性があります。

私は今月初めにこのアプローチについてブログを書きました-http ://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/

この例ではビデオファイルを使用しましたが、原則は同じです。つまり、データのバイトをクライアントにプッシュダウンします。

于 2013-02-04T23:59:55.793 に答える
0

StreamContent(あまりにも新しい?)を使用して、ファイルから直接ストリーミングします。Web API Controllerと同様に、MemoryStream を StreamContent に変換します

httpResponseMessage.Content = new StreamContent(file);
于 2016-10-18T19:25:49.080 に答える