合并和压缩 Azure Blob 存储中的多个大文件
Posted
技术标签:
【中文标题】合并和压缩 Azure Blob 存储中的多个大文件【英文标题】:Combine and Zip Multiple Large Files From Azure Blob Storage 【发布时间】:2022-01-18 22:23:55 【问题描述】:我在 API 后面运行了一些代码,该 API 循环遍历 Azure Blob 存储上的文件列表,将它们压缩并将最终的 Zip 保存到同一个存储帐户。然后我提供一个指向 Zip 文件的链接供我的用户访问。
只要文件很小,此解决方案就可以正常工作。但是,有很多文件在 2-5 GB 范围内,一旦测试这些文件,我就会收到内存不足异常错误:
'数组尺寸超出支持范围。'
我已经看到 OneDrive 和 GoogleDrive 等系统非常快速地创建了这些文件,我渴望为我的用户创造这种体验。但是我也可以在存档准备好下载时通知用户,即使是几分钟后,因为我会收到他们的电子邮件。
以下是简化并在控制台应用程序中运行的代码版本:
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);
【问题讨论】:
【参考方案1】:正如您提到的,它适用于小文件和大文件时会引发错误。
解决方法
1) 上传小块的大文件,然后压缩。
更多详情请参考这个 SO 线程:Upload a zip file in small chunks to azure cloud blob storage
2) 本教程展示了您部署一个将大量随机数据上传到 Azure 存储帐户的应用程序:Upload large amounts of random data in parallel to Azure storage
3)上传大文件,你可以使用Microsoft Azure Storage Data Movement Library以获得更好的性能。 Microsoft Azure 存储数据移动库专为高性能上传、下载和复制 Azure 存储 Blob 和文件而设计
【讨论】:
感谢您的信息,但是我的方案需要一个包含非常大文件的庞大库。用户提交从目录中选择文件的请求以下载它们。因此,可以随时请求各种各样的压缩文件组合。 zip 是根据请求生成的,而不是上传过程的一部分。我想我可能需要让 VM 从事件中获取这些请求,将每个文件复制到它的本地硬盘驱动器,将它们压缩到 VM 上,然后将压缩文件推回 Azure。然后可以在准备好时将链接发送给请求者。如果这可行,我会更新。以上是关于合并和压缩 Azure Blob 存储中的多个大文件的主要内容,如果未能解决你的问题,请参考以下文章
Ionic Zip 密码设置在 azure blob 存储中,并为 zip 文件夹而不是文件设置最佳压缩
如何在不写入文件的情况下压缩流并将其上传到 Azure Blob 存储?