Is ASP.NET MVC's FileStreamResult less efficient than writing directly to the Response Output Stream, or am I missing something?

前端 未结 2 1637
攒了一身酷
攒了一身酷 2021-02-06 01:55

First of all, I love ASP.NET MVC. This question is not a criticism of it. Rather, I want to confirm what I think I see and make sure I haven\'t missed something. Bear w

相关标签:
2条回答
  • 2021-02-06 02:29

    I think the main idea behind FileStreamResult is that you use it when you already have a stream. If you have to create a temporary stream in order to use it, then there is no point; that's why there is also a FilePathResult and FileContentResult.

    There are several instances when you might already have a stream:

    • Data stored in a SQL 2008 FILESTREAM column;
    • Data forwarded directly from another endpoint (NetworkStream);
    • A GzipStream or DeflateStream for sending something compressed;
    • Sending from a named pipe (PipeStream);
    • ...and so on.

    The main use case for FileStreamResult (as I understand it) is when you have a pre-existing stream that you would need to read from and then write back to the response; instead of having to do the reading and writing and figuring out the buffering yourself, the FileStreamResult handles it for you.

    So the short answer is no, FileStreamResult doesn't necessarily force you to have an "intermediate" storage location, if the stream is your data source. I wouldn't bother with FileStreamResult if the data is already in memory or on disk somewhere, ready and waiting to be written directly to the response stream.


    I'd just like to add another clarification: The issue with this library is that it inverts the functionality you really need for FileStreamResult. Instead of handing you a stream that you can read from, it expects you to provide the stream so it can write to it. This is a common pattern, mind you, but it is not very well suited to the task.

    If the stream contains a lot of data and you don't want to chew up memory with it, you should be able to invert the stream yourself using the PipeStream derivatives. Create either a named or anonymous pipe, create a server stream (which you can initialize with as small a buffer size as you want) and feed it to the library, then create a client stream on the same pipe and feed it to the FileStreamResult.

    This gives you the unit-testability you want and lets you control exactly how much memory the process is allowed to use. It also has the added advantage of being able to produce the data asynchronously, which you might want if you're trying to chuck out gigabytes of data.

    0 讨论(0)
  • 2021-02-06 02:34

    I believe it would be more accurate to say that, assuming someObjectThatDumpsOutputToWhateverStreamYouHandIt does not inherit from System.IO.Stream, that using FileStreamResult forces you to either

    a) implement a wrapper for someObjectThatDumpsOutputToWhateverStreamYouHandIt that does inherit from System.IO.Stream, or

    b) use a temporary MemoryStream instance.

    So, it is not necessarily less efficient, but does seem to require a bit more work for the purpose of returning a value.

    Edit by Question Asker: I am choosing this question as the Accepted answer. Both responses were very helpful. I have to choose one, and this one pointed me to Phil Haack's DelegatingActionResult, which is exactly what I needed.

    0 讨论(0)
提交回复
热议问题