'C# How to do on-the-fly compression-and-send in a API controller to avoid large memory buffers

What I am trying to achive is to send a backup (stream) from the API to the requestor, and in the process avoid taking up large amounts of RAM. I have been experimenting using Pipes, but didnt get it to work (probably lack of knowledge ;) )

Take a look at the following routine:

 [HttpGet]
        [Route("{projectIdentifier}")]
        [SwaggerResponse(StatusCodes.Status200OK)]
        [SwaggerResponse(StatusCodes.Status404NotFound)]
        public async Task<IActionResult> BackupProject(string projectIdentifier, bool zipped = false)
        {
            if (!TryGetProject(projectIdentifier, out var project))
                return this.NotFoundResult(nameof(projectIdentifier), projectIdentifier);

            string filenamePartName = $"Project {project.Identifier}";
            string saveFilename = Path.GetInvalidFileNameChars().Aggregate(filenamePartName, (current, c) => current.Replace(c, '_'));

            MemoryStream backupstream = new();
            await Core.Iapetus.Instance.Projects.BackupAsync(backupstream, project.ID, zipped); 
            backupstream.Position = 0;
            var file = zipped ? File(backupstream, "application/zip", $"{saveFilename}.json.gz") : File(backupstream, "application/json", $"{saveFilename}.json");
            return file;
        }

The BackupAsync routine supports compression using the GZipSTream class, and this works on-the fly. Unfortunately the compressed (or not) result still lands in the backupstream memory buffer taking up way much more space than I like in some cases.

The question

Is there a way to "skip" the memory buffer, and send the data directly from the (compressed) stream to the File response? And -off course- keeping the whole shabang async

TIA



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source