I am trying to send a large file using FileStreamResult
-
return new UnbufferedFileStreamResult(new FileStream(apiResponse.url, FileMode.Open, FileAccess.Read), "text/csv") { FileDownloadName = new FileInfo(apiResponse.url).Name };
The UnbufferedFileStreamResult
is:
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);
}
}
This seems to work for files up to a certain size, but if they get too big I get the following exception:
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
So it appears that FileStreamResultExecutorBase
is copying my file stream into a memory stream before it goes to the http output stream. My questions are 1) why is it doing this, 2) how can I prevent this behavior, and 3) are there implementations of results like FileStreamResult
that can read directly from the input stream to the output stream without copying to memory first?