【问题标题】:C# big filedownload resumable from azure blob storageC# 大文件下载可从 azure blob 存储恢复
【发布时间】:2021-03-26 02:04:59
【问题描述】:

我真的需要一些橡皮鸭……

我有一个至少 2.3 GiB 的文件。 我目前正在将此文件下载到临时目录。 但是当下载中断(连接错误或 Windows 崩溃)时,我希望用户在它停止的地方恢复下载。并且不要重新下载整个文件。 该代码的工作原理是它继续下载文件,但我看到下载流再次从头开始。所以这意味着文件最终是(2.3 GiB + 之前下载的字节数),这会损坏我的文件。

我使用以下 sn-p 来恢复下载,所以我希望流能够恢复,它停止的地方 localStream.Seek(positionInFile, SeekOrigin.Begin);

关于我在这里缺少什么的任何想法? 这是我的代码。

                BlobContainerClient containerClient = new BlobContainerClient(connectionString, container);
                var blobClient = containerClient.GetBlobClient(downloadFile);

                fullOutputPath = createOutputFilePath(updateFileUri.OriginalString, outputFolder);
                downloadFileInfo = new FileInfo(fullOutputPath);

                var response = blobClient.Download(cts.Token);
                contentLength = response.Value.ContentLength;
                if (contentLength.HasValue && contentLength.Value > 0)
                {
                    if (_fileSystemService.FileExists(fullOutputPath))
                    {
                        from = downloadFileInfo.Length;
                        to = contentLength;

                        if (from == to)
                        {
                            //file is already downloaded
                            //skip it
                            progress.Report(1);
                            return;
                        }
                        fileMode = FileMode.Open;
                        positionInFile = downloadFileInfo.Length;
                    }

                    using FileStream localStream = _fileSystemService.CreateFile(fullOutputPath, fileMode, FileAccess.Write);
                    localStream.Seek(positionInFile, SeekOrigin.Begin);

                    bytesDownloaded = positionInFile;
                    double dprog = ((double)bytesDownloaded / (double)(contentLength.Value + positionInFile));
                    do
                    {
                        bytesRead = await response.Value.Content.ReadAsync(buffer, 0, buffer.Length, cts.Token);

                        await localStream.WriteAsync(buffer, 0, bytesRead, cts.Token);
                        await localStream.FlushAsync();

                        bytesDownloaded += bytesRead;
                        dprog = ((double)bytesDownloaded / (double)(contentLength.Value + positionInFile));
                        progress.Report(dprog);

                    } while (bytesRead > 0);
                }

【问题讨论】:

  • 你可以使用 range 分块下载 public Download(HttpRange range = default, BlobRequestConditions conditions = null, bool rangeGetContentHash = false, CancellationToken cancellationToken = default);

标签: c# azure azure-storage


【解决方案1】:

我为您做了一些测试,就我而言,我使用 .txt 文件来演示您的要求。您可以看到.txt 文件here。 如您所见,在第 151 行,我做了一个结束标记:

我还创建了一个以这个结束标记结尾的本地文件,以模拟下载被中断,我们将继续从存储中下载:

这是我下面的快速演示代码:

static void Main(string[] args)
{
    string containerName = "container name";
    string blobName = ".txt file name";
    string storageConnStr = "storage account conn str";

    string localFilePath = @"local file path";

    var localFileStream = new FileStream(localFilePath, FileMode.Append);

    var localFileLength = new FileInfo(localFilePath).Length;

    localFileStream.Seek(localFileLength, SeekOrigin.Begin);


    var blobServiceClient = new BlobServiceClient(storageConnStr);
    var blobClient = blobServiceClient.GetBlobContainerClient(containerName).GetBlobClient(blobName);

    var stream = blobClient.Download(new Azure.HttpRange(localFileLength)).Value.Content;

    var contentStrting = new StreamReader(stream).ReadToEnd();

    Console.WriteLine(contentStrting);

    localFileStream.Write(Encoding.ASCII.GetBytes(contentStrting));
    localFileStream.Flush();
}

结果: 我们只下载了结束标记后面的内容:

内容已下载到本地 .txt 文件:

如果您还有任何问题,请告诉我。

【讨论】:

  • 这真的很有希望我要去测试它...谢谢哥们
  • 嗨@Henkie85,你的问题解决了吗?
猜你喜欢
  • 2021-12-08
  • 2020-08-08
  • 2016-02-29
  • 2018-03-11
  • 2015-06-20
  • 2021-12-05
  • 2018-04-25
相关资源
最近更新 更多