【问题标题】:Streaming large images using ASP.Net Webapi使用 ASP.Net Webapi 流式传输大图像
【发布时间】:2013-01-19 18:54:03
【问题描述】:

我们正在尝试使用 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 编程模型来使用类似的技术?

【问题讨论】:

    标签: c# asp.net-web-api download streaming large-files


    【解决方案1】:

    是的,您可以使用PushStreamContent。如果你将它与异步执行(使用即异步 lambda)结合起来,你可能会得到更有效的结果。

    本月早些时候,我在博客中介绍了这种方法 - http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/

    例子中使用了一个视频文件,原理相同——将字节数据下推到客户端。

    【讨论】:

    • @FIllip W - 首先,非常感谢您的帮助。我没有使用 4.5 框架的奢侈,所以我不能使用 4.5 框架的内置异步功能。这种方法可以使用 4.0 框架库吗?更具体地说,“WriteToStream”操作将如何变化?我可以只读取每个字节块并写入输出流而不用担心异步部分吗?
    • 是的,Web API 中的所有内容都与 4.0 兼容。您可以删除 async/await 并使整个事情同步,或者在等待代码的任何地方使用延续 (ContinueWith)。
    • @FIllip W - 这对我来说效果很好。再次感谢您的帮助。我已经接受了你的回答。再次感谢
    【解决方案2】:

    使用StreamContent 直接从文件流式传输(太新?)。类似于Web API Controller convert MemoryStream into StreamContent

    httpResponseMessage.Content = new StreamContent(file);
    

    【讨论】:

    • 我在这个实现中遇到了严重的问题(比如下载未完成)。有些东西让客户认为它没有所有的内容!
    • @NormanH 很奇怪,我认为有些东西正在“中断”下载,客户端放弃是因为服务器上的某些东西“太长”了,或者你可能不小心破坏了原始文件流?我以前做过,将一个流放入某个东西,然后过早地处理一个读取器/写入器(这会关闭它正在作用的流,具体取决于设置)。也许您正在限制文件读取,或者源文件在流式传输过程中被移动/删除?
    猜你喜欢
    • 2014-11-03
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 2022-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 2021-10-03
    相关资源
    最近更新 更多