C# 通过慢速网络下载大文件时发生StorageException
我正在使用NuGet软件包WindowsAzure.Storage4.2.1版 下面的代码尝试从远程数据中心中的存储容器下载blobC# 通过慢速网络下载大文件时发生StorageException,c#,exception,azure,azure-storage,azure-storage-blobs,C#,Exception,Azure,Azure Storage,Azure Storage Blobs,我正在使用NuGet软件包WindowsAzure.Storage4.2.1版 下面的代码尝试从远程数据中心中的存储容器下载blob try { var blobRequestOptions = new BlobRequestOptions { RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(5), 3), MaximumExecutionTime = TimeSpan.FromMin
try
{
var blobRequestOptions = new BlobRequestOptions
{
RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(5), 3),
MaximumExecutionTime = TimeSpan.FromMinutes(60),
ServerTimeout = TimeSpan.FromMinutes(60)
};
using (var fileStream = File.Create(localPath))
{
blockBlob.DownloadToStream(fileStream, null, blobRequestOptions);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
但是,有时它会下载约10分钟,然后抛出以下异常:
Unhandled Exception: Microsoft.WindowsAzure.Storage.StorageException: The client could not finish the operation within specified timeout. ---> System.TimeoutException: The client could not finish the operation within specified timeout.
--- End of inner exception stack trace ---
at Microsoft.WindowsAzure.Storage.Core.Util.StorageAsyncResult`1.End()
at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.EndUploadText(IAsyncResult asyncResult)
at Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.<>c__DisplayClass4.b__3(IAsyncResult ar)
--- End of stack trace from previous location where exception was thrown ---
未处理的异常:Microsoft.WindowsAzure.Storage.StorageException:客户端无法在指定的超时内完成操作。-->System.TimeoutException:客户端无法在指定的超时内完成操作。
---内部异常堆栈跟踪的结束---
在Microsoft.WindowsAzure.Storage.Core.Util.StorageAsyncResult`1.End()中
位于Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.EndUploadText(IAsyncResult asyncResult)
在Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.c__DisplayClass4.b__3(IAsyncResult ar)上
---来自引发异常的上一个位置的堆栈结束跟踪---
如何修复此问题?请尝试此代码。基本上,它所做的是先创建一个空文件,然后使用方法以1MB块的形式读取blob的数据。下载块时,它会将其附加到文件中
private static void DownloadLargeFile()
{
var account = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("container-name");
var file = "my-very-large-file-name";
var blob = container.GetBlockBlobReference(file);
//First fetch the size of the blob. We use this to create an empty file with size = blob's size
blob.FetchAttributes();
var blobSize = blob.Properties.Length;
long blockSize = (1 * 1024 * 1024);//1 MB chunk;
blockSize = Math.Min(blobSize, blockSize);
//Create an empty file of blob size
using (FileStream fs = new FileStream(file, FileMode.Create))//Create empty file.
{
fs.SetLength(blobSize);//Set its size
}
var blobRequestOptions = new BlobRequestOptions
{
RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(5), 3),
MaximumExecutionTime = TimeSpan.FromMinutes(60),
ServerTimeout = TimeSpan.FromMinutes(60)
};
long currentPointer = 0;
long bytesRemaining = blobSize;
do
{
var bytesToFetch = Math.Min(blockSize, bytesRemaining);
using (MemoryStream ms = new MemoryStream())
{
//Download range (by default 1 MB)
blob.DownloadRangeToStream(ms, currentPointer, bytesToFetch, null, blobRequestOptions);
ms.Position = 0;
var contents = ms.ToArray();
using (var fs = new FileStream(file, FileMode.Open))//Open that file
{
fs.Position = currentPointer;//Move the cursor to the end of file.
fs.Write(contents, 0, contents.Length);//Write the contents to the end of file.
}
currentPointer += contents.Length;//Update pointer
bytesRemaining -= contents.Length;//Update bytes to fetch
}
}
while (bytesRemaining > 0);
}
我在一个小文件上尝试了这段代码(互联网连接不良:p)。因此,请先在一个小文件(比如5-10MB)上试用,然后再试用500MB的文件。HTH.这个水滴有多大?@GauravMantri大约500兆谢谢。分块下载是一种选择吗?基本上,我们的想法是将这个大blob下载成更小的块,然后在下载块时构建文件。是的,我想是这样,如果它有效:)你能提供一个代码示例吗?一个问题:如果文件存在,它会先被完全删除,然后被覆盖吗?是的<代码>文件模式。创建可执行此操作。您也可以使用
FileMode.open或create
。好啊另一个问题:我正在使用您的代码下载zip文件,但其中一些文件已损坏。你知道为什么会这样吗?请检查blob的大小和下载文件的大小是否相同。文件是否可能在上传时损坏?是的,它们是相同的。所讨论的zip文件是一个大文件,我甚至不能区分它们,因为它们太大了。然而,我确实在KDiff的底部看到了一行“未解决的冲突:1”。。