gpt4 book ai didi

c# - ASP.NET MVC 的 FileStreamResult 是否比直接写入响应输出流效率低,还是我遗漏了什么?

转载 作者:太空狗 更新时间:2023-10-29 17:41:08 27 4
gpt4 key购买 nike

首先,我喜欢 ASP.NET MVC。这个问题不是对它的批评。相反,我想确认我所看到的,并确保我没有遗漏任何东西。请耐心等待……如果不提供一点上下文,我就无法回答这个问题。

问题与响应 HTTP Post 时在 Stream 中返回数据有关。在 ASP.NET MVC 之前的过去,您可以通过将数据直接输送到响应流来实现这一点。例如,您可以这样做:

someObjectThatDumpsOutputToWhateverStreamYouHandIt.WriteTo(Response.OutputStream); 

请注意此代码的一个关键方面:我还没有实现任何 后备存储。我不必将信息流式传输到字节数组,或将其转储到临时文件中。相反,ASP.NET 已经设置了一个 Stream,目的是将响应传回浏览器,我已经将我想要的输出直接转储到该 Stream 中。就 CPU、内存和执行时间而言,这比将所有数据复制到某个临时位置然后将其移动到响应流中更有效。

但是对单元测试不是很友好。事实上,您仍然可以在 ASP.NET MVC 中执行此类代码,但习惯上会避免这种情况。相反,ASP.NET MVC 会鼓励您返回一个 ActionResult。 ActionResult 是一个 ASP.NET MVC 概念,其存在主要是为了便于单元测试。它允许你“声明”你想做什么。单元测试可以执行 Controller 操作并确认它获得预期的 ActionResult。该单元测试可以在浏览器之外运行。

ASP.NET MVC 提供了一种用于返回数据流的 ActionResult。它称为 FileStreamResult。不要让名称中的"file"一词欺骗了您。它是关于返回一个数据流,正如我们上面所说的。

但是,这里是问题所在,也是我的问题的基础:如果您让您的 Controller 方法返回一个 FileStreamResult,并且您将一个要返回的 Stream 传递给它,那么看起来就没有任何办法了以便您将数据直接转储到 Response 流。 现在,您似乎被迫使用后备存储(例如内存或文件)创建自己的 Stream,将数据转储到其中,然后将该 Stream 到您返回的 FileStreamResult。

所以看起来我必须做这样的事情(有意省略处置/使用/等):

MemoryStream myIntermediateStream = new MemoryStream();
someObjectThatDumpsOutputToWhateverStreamYouHandIt.WriteTo(myIntermediateStream );

return new FileStreamResult(myIntermediateStream, "application/pdf");

注意 myIntermediateStream 导致大数据流的内容暂时存储在内存中,以便 FileStreamResult 稍后可以再次将其复制到响应输出流中。

所以这是我的问题:我是不是忽略了什么,或者说使用 FileStreamResult 会强制您拥有一个中间存储位置是否准确,如果您直接写入 Response's输出流?

谢谢。

最佳答案

我认为FileStreamResult 背后的主要思想是当您已经 一个流时使用它。如果您必须创建一个临时流才能使用它,那就没有意义了;这就是为什么还有 FilePathResultFileContentResult

几种情况下您可能已经有一个流:

  • 数据存储在 SQL 2008 FILESTREAM 列中;
  • 直接从另一个端点转发的数据(NetworkStream);
  • GzipStreamDeflateStream 用于发送压缩内容;
  • 从命名管道发送 (PipeStream);
  • ...等等。

FileStreamResult 的主要用例(据我所知)是当您有一个预先存在的流时,您需要读取然后回复回复; FileStreamResult 会为您处理,而不是您自己进行读写和计算缓冲。

所以简短的回答是否定的,如果流是您的数据FileStreamResult 不一定会强制您拥有“中间”存储位置。如果数据已经在内存中或磁盘上的某个地方,准备好等待直接写入响应流,我就不会为 FileStreamResult 而烦恼。


我只想补充说明:这个库的问题是它颠倒了 FileStreamResult 真正需要的功能。它不是给你一个你可以读取的流,而是希望你提供流以便它可以写入它。请注意,这是一种常见的模式,但它不太适合这项任务。

如果流包含大量数据并且您不想用它来占用内存,您应该能够使用 PipeStream 自行反转流。衍生品。创建一个命名或匿名管道,创建一个服务器流(您可以根据需要使用尽可能小的缓冲区大小对其进行初始化)并将其提供给库,然后在同一管道上创建一个客户端流并将其提供给 FileStreamResult.

这为您提供了所需的单元可测试性,并让您准确控制允许进程使用的内存量。它还具有能够异步生成数据的额外优势,如果您试图丢弃数 GB 的数据,您可能需要这种方式。

关于c# - ASP.NET MVC 的 FileStreamResult 是否比直接写入响应输出流效率低,还是我遗漏了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2189435/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com