Подтвердить что ты не робот

Вызывается ли Stream при возврате файла из действия?

Я записываю строку в MemoryStream, мне нужно вернуть поток в действие контроллера, чтобы я мог отправить его в виде файла для загрузки.

Обычно я заключаю Stream в оператор using, но в этом случае мне нужно его вернуть. Утилизируется ли он после того, как я его верну? Или мне как-то самому распоряжаться?

//inside CsvOutputFormatter
public Stream GetStream(object genericObject)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream, Encoding.UTF8);
    writer.Write(_stringWriter.ToString());
    writer.Flush();
    stream.Position = 0;
    return stream;
}

Действие контроллера, которое возвращает файл:

[HttpGet]
[Route("/Discussion/Export")]
public IActionResult GetDataAsCsv()
{
    var forums = _discussionService.GetForums(_userHelper.UserId);

    var csvFormatter = new CsvOutputFormatter(new CsvFormatterOptions());

    var stream = csvFormatter.GetStream(forums);
    return File(stream, "application/octet-stream", "forums.csv");

    //is the stream Disposed here automatically?
}
4b9b3361

Ответ 1

В соответствии с исходным кодом здесь aspnet/AspNetWebStack/blob/master/src/System.Web.Mvc/FileStreamResult.cs

Да

protected override void WriteFile(HttpResponseBase response)
{
    // grab chunks of data and write to the output stream
    Stream outputStream = response.OutputStream;
    using (FileStream)
    {
        byte[] buffer = new byte[BufferSize];

        while (true)
        {
            int bytesRead = FileStream.Read(buffer, 0, BufferSize);
            if (bytesRead == 0)
            {
                // no more data
                break;
            }

            outputStream.Write(buffer, 0, bytesRead);
        }
    }
}

Где FileStream был бы поток, переданный при вызове

return File(stream, "application/octet-stream", "forums.csv");

Update.

Ваш вопрос был изначально помечен как Asp.Net MVC, но код выглядит как более новая базовая структура.

Нашел его там, хотя написано по-другому, технически он делает то же самое.

ASPnet/AspNetCore/блоб/ведущий /SRC/Mvc/Mvc.Core/SRC/Инфраструктура /FileResultExecutorBase.cs

protected static async Task WriteFileAsync(HttpContext context, Stream fileStream, RangeItemHeaderValue range, long rangeLength)
{
    var outputStream = context.Response.Body;
    using (fileStream)
    {
        try
        {
            if (range == null)
            {
                await StreamCopyOperation.CopyToAsync(fileStream, outputStream, count: null, bufferSize: BufferSize, cancel: context.RequestAborted);
            }
            else
            {
                fileStream.Seek(range.From.Value, SeekOrigin.Begin);
                await StreamCopyOperation.CopyToAsync(fileStream, outputStream, rangeLength, BufferSize, context.RequestAborted);
            }
        }
        catch (OperationCanceledException)
        {
            // Don't throw this exception, it most likely caused by the client disconnecting.
            // However, if it was cancelled for any other reason we need to prevent empty responses.
            context.Abort();
        }
    }
}