Вопрос по c#, asp.net-core, asp.net-core-mvc, streamwriter, memorystream – Располагается ли поток при возврате файла из действия? [Дубликат]

10

На этот вопрос уже есть ответ:

FileStreamResult закрывает поток? 1 ответ Как избавиться от файлового потока при загрузке файлов в ASP.NET 2 ответа

Я пишу строку в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;
}

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

[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?
}
Хороший вопрос. За исключением явной документации, говорящей так (на самом деле не выглядело), вы можете реализовать свой собственный поток и проверить, вызывался ли когда-либо его метод dispose. Rob♦

Ваш Ответ

1   ответ
10

Согласно исходному коду здесь aspnetwebstack / 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");

Обновить

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

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

САШ / Mvc / BLOB / DEV / SRC / Microsoft.AspNetCore.Mvc.Core / Инфраструктура / FileStreamResultExecutor.cs

private static async Task WriteFileAsync(ActionContext context, FileStreamResult result)
{
    var response = context.HttpContext.Response;
    var outputStream = response.Body;

    using (result.FileStream)
    {
        await result.FileStream.CopyToAsync(outputStream, BufferSize);
    }
}

Похожие вопросы