FileStreamResult в ядре ASP.NET большого файла (> 2 ГБ) приводит к исключению System.IO.IOException: поток слишком длинный - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь отправить большой файл, используя FileStreamResult -

return new UnbufferedFileStreamResult(new FileStream(apiResponse.url, FileMode.Open, FileAccess.Read), "text/csv") { FileDownloadName = new FileInfo(apiResponse.url).Name };

UnbufferedFileStreamResult:

public class UnbufferedFileStreamResult : FileStreamResult {
    public UnbufferedFileStreamResult(Stream fileStream, string contentType) : base(fileStream, contentType) {

    }

    public override void ExecuteResult(ActionContext context) {
        context.HttpContext.DisableOutputBuffering();
        base.ExecuteResult(context);
    }
}

Кажется, это работает для файлов до определенногоразмер, но если они становятся слишком большими, я получаю следующее исключение:

System.IO.IOException: Stream was too long.
   at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.MemoryStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Http.Extensions.StreamCopyOperation.CopyToAsync(Stream source, Stream destination, Nullable`1 count, Int32 bufferSize, CancellationToken cancel)
   at Microsoft.AspNetCore.Mvc.Infrastructure.FileResultExecutorBase.WriteFileAsync(HttpContext context, Stream fileStream, RangeItemHeaderValue range, Int64 rangeLength)
   at Microsoft.AspNetCore.Mvc.Infrastructure.FileStreamResultExecutor.ExecuteAsync(ActionContext context, FileStreamResult result)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, O

Таким образом, получается, что FileStreamResultExecutorBase копирует мой файловый поток в поток памяти, прежде чем он попадает в поток вывода http.Мои вопросы: 1) почему он это делает, 2) как я могу предотвратить такое поведение, и 3) существуют ли реализации результатов типа FileStreamResult, которые могут считывать данные непосредственно из входного потока в выходной поток без предварительного копирования в память?

...