[英]Download large zip file from azure blob and unzip
我目前有以下代碼,它使用 SAS URI 從 blob 下載 zip 文件,解壓縮並將內容上傳到新容器
var response = await new BlobClient(new Uri(sasUri)).DownloadAsync();
using (ZipArchive archive = new ZipArchive(response.Value.Content))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
BlobClient blobClient = _blobServiceClient.GetBlobContainerClient(containerName).GetBlobClient(entry.FullName);
using (var fileStream = entry.Open())
{
await blobClient.UploadAsync(fileStream, true);
}
}
}
我的代碼因“流太長”異常而失敗: System.IO.IOException:流太長。 在 System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) 在 System.IO.Stream.CopyTo(Stream destination, Int32 bufferSize) 在 System.IO.Compression.ZipArchive.Init(Stream stream, ZipArchiveMode模式,布爾值 leaveOpen) 。
我的 zip 文件大小為 9G。 解決此異常的更好方法是什么? 我想避免將任何文件寫入磁盤。
所以這里的問題是
因此,您將需要允許更大的對象(以某種方式)
<gcAllowVeryLargeObjects>
項目元素COMPlus_gcAllowVeryLargeObjects
然而,在大對象堆上放置 9 gig 的任何東西都是有問題的,它對於 GC 和其他問題來說效率低下,你應該盡可能地避免 LOH。
注意取決於圖書館,以及您可以訪問的內容。 可能有更少的LOHy方法來做到這一點。 如果你可以提供你自己的流/數據結構,那么有一些庫可以分解緩沖區,這樣它們就不會通過ReadOnlySequence
和微軟鮮為人知的RecyclableMemoryStream
類的東西在 LOH 上積極分配。
以下解決方案對我有用。 不要使用 DownloadAsync,而是使用 OpenReadAsync
var response = await new BlobClient(new Uri(sasUri)).OpenReadAsync(new BlobOpenReadOptions(false), cancellationToken);
using (ZipArchive archive = new ZipArchive(response))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
BlobClient blobClient = _blobServiceClient.GetBlobContainerClient(containerName).GetBlobClient($"{buildVersion}/{entry.FullName}");
using (var fileStream = entry.Open())
{
await blobClient.UploadAsync(fileStream, true, cancellationToken).ConfigureAwait(false);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.