【问题标题】:StorageException when downloading a large file over a slow network通过慢速网络下载大文件时出现 StorageException
【发布时间】:2015-09-16 16:49:51
【问题描述】:

我正在使用 NuGet 包WindowsAzure.Storage 4.2.1 版。

以下代码尝试从位于远程数据中心的存储容器下载 Blob。

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 ---

我该如何解决这个问题?

【问题讨论】:

  • blob 有多大?
  • @GauravMantri 大约 500 MB
  • 谢谢。分块下载是一种选择吗?基本上,这个想法是您以较小的块下载这个大 blob,然后在下载块时构建文件。
  • 是的,我想是的,如果可行的话:) 你能提供一个代码示例吗?

标签: c# exception azure azure-storage azure-blob-storage


【解决方案1】:

请尝试此代码。基本上它的作用是首先创建一个空文件,然后使用DownloadRangeToStream 方法以 1 MB 块读取 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)。因此,在尝试使用 500 MB 文件之前,请先在一个小文件(比如 5 - 10 MB 左右)上进行尝试。 HTH。

【讨论】:

  • 一个问题:如果文件存在,会不会先彻底删除再覆盖?
  • 是的。 FileMode.Create 就是这样做的。您也可以改用FileMode.OpenOrCreatemsdn.microsoft.com/en-us/library/…
  • 好的。另一个问题:我正在使用您的代码下载 zip 文件,但其中一些文件已损坏。您对为什么会这样有任何想法吗?
  • 请检查blob大小和下载文件大小是否一致。是否有可能即使在上传时文件也已损坏?
  • 是的,它们是一样的。有问题的 zip 文件是大文件,我什至无法区分它们,因为它们太大了。但是,我确实在 KDiff 的底部看到了一行“未解决的冲突:1”..
猜你喜欢
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
相关资源
最近更新 更多