I have some code running behind an API that loops through a list of files on Azure Blob Storage, Zips them up and saves the final Zip to the same storage account. I then provide a link to the Zip file for my users to access.
This solution works fine provided the files are small. However there are many files in the 2-5 GB range and as soon as these are tested I get an out of memory exception error:
'Array dimensions exceeded supported range.'
I've seen systems like OneDrive and GoogleDrive create these files very quickly and I aspire to creating that experience for my users. But I am also fine with notifying the user when the archive is ready to download even if it is a few minutes later as I will have their email.
Here is a version of the code simplified and running in a console app:
using Microsoft.WindowsAzure.Storage;
using System.IO.Compression;
var account = CloudStorageAccount.Parse("ConnectionString");
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("ContainerName");
var blob = container.GetBlockBlobReference("ZipArchive.zip");
using (var stream = await blob.OpenWriteAsync())
using (var zip = new ZipArchive(stream, ZipArchiveMode.Create))
{
var files = new string[] {
"files/psds/VeryLargePsd_1.psd",
"files/psds/VeryLargePsd_2.psd",
"files/psds/VeryLargePsd_3.psd",
"files/zips/VeryLargeZip_1.zip",
"files/zips/VeryLargeZip_2.zip"
};
foreach (var file in files)
{
var sourceBlob = container.GetBlockBlobReference(file);
var index = file.LastIndexOf('/') + 1;
var fileName = file.Substring(index, file.Length - index);
var entry = zip.CreateEntry(fileName, CompressionLevel.Optimal);
await sourceBlob.FetchAttributesAsync();
byte[] imageBytes = new byte[sourceBlob.Properties.Length];
await sourceBlob.DownloadToByteArrayAsync(imageBytes, 0);
using (var zipStream = entry.Open())
zipStream.Write(imageBytes, 0, imageBytes.Length);
}
}