memorystreamnancysqlfilestream

Stream an (SqlFile-)Stream using Nancy


I was wondering how to send an (in my case) SqlFileStream directly to the client through our Nancy-API without loading the stream in memory.

So far I succeeded in passing the stream, but Nancy's StreamResponse copies the sourcestream (=SqlFileStream) to the outputstream which causes a massive memory increase. Where I would just like it to send the stream through.

I made this work in WebApi where WebApi was registered in the Owin-pipeline. No memory increase is noticeable, which is great when we are talking about pretty big streams (>100MB). But of course I'd rather stick to one API-application-framework if possible.

Any tips?


Solution

  • I think I found a solution. It wasn't too difficult to do in the end.

    I created a custom Nancy.Response => FlushingStreamResponse. Passing it a stream and a mimetype, results in immediate streaming to the client when this is the result of our GET.

    public class FlushingStreamResponse : Response
    {
        public FlushingStreamResponse(Stream sourceStream, string mimeType)
        {
            Contents = (stream) =>
            {
                var buffer = new byte[16 * 1024];
                int read;
                while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    stream.Write(buffer, 0, read);
                    stream.Flush();
                }
                sourceStream.Dispose();
            };
    
            StatusCode = HttpStatusCode.OK;
            ContentType = mimeType;
        }
    }