我现在有下面的代码,它使用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: Stream太长了。在System.IO.MemoryStream.Write(Byte[]缓冲器,Int32偏移,Int32计数)的System.IO.Stream.CopyTo(流目的地,Int32 bufferSize)的System.IO.Compression.ZipArchive.Init(流流,ZipArchiveMode模式,布尔leaveOpen)。
我的压缩文件大小是9G。有什么更好的方法来避开这个例外呢?我想避免将任何文件写入磁盘。
发布于 2022-01-18 00:57:16
下面的解决方案对我有用。不要使用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);
}
}
}发布于 2020-11-20 02:40:43
所以这里的问题是
因此,您需要允许较大的对象(以某种方式)
<gcAllowVeryLargeObjects>项目元素COMPlus_gcAllowVeryLargeObjects但是,在大型对象堆上放置9组任何东西都是有问题的,对于GC和其他问题来说,这是效率低下的,您应该尽可能地避免LOH。
注取决于库和您可以访问的内容。可能有更少的LOHy方法来做到这一点。如果您可以提供您自己的流/数据结构,那么有一些库可以分解缓冲区,这样它们就不会通过ReadOnlySequence和Microsofts之类的东西在LOH上得到积极的分配,很少有人知道RecyclableMemoryStream。
https://stackoverflow.com/questions/64922803
复制相似问题