[英]Upload a zip file in small chunks to azure cloud blob storage
我想將小塊(小於 5 MB)的 zip 文件上傳到 Microsoft Azure 存儲中的 blob 容器。 我已經在 BlobRequestOptions 中配置了 4 MB 塊限制,但是當我運行我的代碼並檢查 Azure Cloud 中的內存使用情況時,它沒有以塊的形式上傳。 我正在使用 C# .NET Core。 因為我想壓縮已經位於 Azure 雲中的文件,所以首先我下載單個文件進行流式傳輸,將流添加到 zip 存檔,然后將 zip 上傳回雲。 以下是我的代碼:
if (CloudStorageAccount.TryParse(_Appsettings.GetSection("StorConf").GetSection("StorageConnection").Value, out CloudStorageAccount storageAccount)) {
CloudBlobClient BlobClient = storageAccount.CreateCloudBlobClient();
TimeSpan backOffPeriod = TimeSpan.FromSeconds(2);
int retryCount = 1;
BlobRequestOptions bro = new BlobRequestOptions() {
SingleBlobUploadThresholdInBytes = 4096 * 1024, // 4MB
ParallelOperationThreadCount = 1,
RetryPolicy = new ExponentialRetry(backOffPeriod, retryCount),
// new
ServerTimeout = TimeSpan.MaxValue,
MaximumExecutionTime = TimeSpan.FromHours(3),
//EncryptionPolicy = policy
};
// set blob request option for created blob client
BlobClient.DefaultRequestOptions = bro;
// using specified container which comes via transaction id
CloudBlobContainer container = BlobClient.GetContainerReference(transaction id);
using(var zipArchiveMemoryStream = new MemoryStream()) {
using(var zipArchive = new ZipArchive(zipArchiveMemoryStream, ZipArchiveMode.Create, true)) // new
{
foreach(FilesListModel FileName in filesList) {
if (await container.ExistsAsync()) {
CloudBlob file = container.GetBlobReference(FileName.FileName);
if (await file.ExistsAsync()) {
// zip: get stream and add zip entry
var entry = zipArchive.CreateEntry(FileName.FileName, CompressionLevel.Fastest);
// approach 1
using(var entryStream = entry.Open()) {
await file.DownloadToStreamAsync(entryStream, null, bro, null);
await entryStream.FlushAsync();
entryStream.Close();
}
} else {
downlReady = "false";
}
} else {
// case: Container does not exist
//return BadRequest("Container does not exist");
}
}
}
if (downlReady == "true") {
string zipFileName = "sample.zip";
CloudBlockBlob zipBlockBlob = container.GetBlockBlobReference(zipFileName);
zipArchiveMemoryStream.Position = 0;
//zipArchiveMemoryStream.Seek(0, SeekOrigin.Begin);
// new
zipBlockBlob.Properties.ContentType = "application/x-zip-compressed";
await zipArchiveMemoryStream.FlushAsync();
await zipBlockBlob.UploadFromStreamAsync(zipArchiveMemoryStream, zipArchiveMemoryStream.Length, null, bro, null);
}
zipArchiveMemoryStream.Close();
}
}
以下是azure cloud kudu process explorer中內存使用情況的快照(見private_Memory):
任何建議都會非常有幫助。 謝謝你。
更新1:
為了更清楚。 我的文件已經位於 Azure blob 存儲中。 現在我想從容器中讀取文件,創建一個包含我所有文件的 ZIP。 這里的主要挑戰是我的代碼顯然是將所有文件加載到內存中以創建 zip。 是否以及如何從容器中讀取文件並將 ZIP 文件並行/分段寫回同一個容器,以便我的 Azure Web 應用程序不需要將整個文件加載到內存中? 理想情況下,我會分塊讀取文件並開始編寫 zip 文件,以便我的 Azure Web 應用程序消耗更少的內存。
我通過參考這篇stackoverflow文章找到了解決方案:
如何將文件動態添加到 Azure blob 存儲中存儲的 zip 存檔?
這樣做的方法是在讀取/下載輸入文件的同時寫入 zip 內存流。
下面是我的代碼片段:
using (var zipArchiveMemoryStream = await zipBlockBlob.OpenWriteAsync(null, bro, null))
using (var zipArchive = new ZipArchive(zipArchiveMemoryStream, ZipArchiveMode.Create))
{
foreach (FilesListModel FileName in filesList)
{
if (await container.ExistsAsync())
{
CloudBlob file = container.GetBlobReference(FileName.FileName);
if (await file.ExistsAsync())
{
// zip: get stream and add zip entry
var entry = zipArchive.CreateEntry(FileName.FileName, CompressionLevel.Fastest);
// approach 1
using (var entryStream = entry.Open())
{
await file.DownloadToStreamAsync(entryStream, null, bro, null);
entryStream.Close();
}
}
}
}
zipArchiveMemoryStream.Close();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.