Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过慢速网络下载大文件时发生StorageException_C#_Exception_Azure_Azure Storage_Azure Storage Blobs - Fatal编程技术网

C# 通过慢速网络下载大文件时发生StorageException

C# 通过慢速网络下载大文件时发生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

我正在使用NuGet软件包WindowsAzure.Storage4.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 ---
未处理的异常: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”。。