Proxy file stream from Azure FileShare to the user

Published by boczek on

The case:

We’ve got Azure FileShare with files around 1GB and ASP.Net Core app that allow the user to download them. So our API should act as a proxy.

FileShare (stores files)→ API (proxy files) → USER (downloads file)

Problems:

The problem that we’ve had was the slow download and a lot of memory consumed by the app.

Solution:

The first thing we did was saving gzipped files to Azure FileShare. The less you sent by the network the faster transfer you got – simple as that.

The next thing is the fact, that our API should act as a proxy, it should only redirect stream to the user. There is no need to download the whole file to the memory.

So what we’ve done here:

  • We use the downloadAsync to get the FileStream from Azure FileShare
  • Then we turn it into GZipStream with decompress mode – to return to the user unzipped file
  • And finally, return it to the user as FileStreamResult
// Controller:
[HttpGet]
public async Task<IActionResult> Get()
{
    // Gets decompressed gzip stream
    var stream = await new FileShareClient().GetFileAsync("Test1.csv.gz");
    // Return it as a filestream
    return new FileStreamResult(stream, "application/octet-stream")
    {
        FileDownloadName = "Test1.csv"
    };
}

// FileShareClient:
public async Task<Stream> GetFileAsync(string fileName)
{
    // Get a reference to the file
    var share = new ShareClient(connectionString, shareName);
    var directory = share.GetDirectoryClient(dirName);
    var file = directory.GetFileClient(fileName);

    // Download the file
    var download = await file.DownloadAsync();
    // As we have access to the file stream, we should decompress it
    // We do it to improve user experience, that received normal csv instead gzipped one
    return new GZipStream(download.Value.Content, CompressionMode.Decompress);
}

0 Comments

Leave a Reply

Your email address will not be published.