【问题标题】:How to calculate the total size of Blob storage containers in an storage account when using the new Azure.Storage.Blobs使用新的 Azure.Storage.Blobs 时如何计算存储帐户中 Blob 存储容器的总大小
【发布时间】:2020-11-02 02:15:38
【问题描述】:

过去一两年我一直在使用Microsoft.Azure.Storage.Blob,这就是我计算所有容器大小的方式:

    var myStorageAccount = CloudStorageAccount.Parse(myConnectionString, string.Empty));
    var myClient = myStorageAccount.CreateCloudBlobClient();

    var myContainers = myClient.ListContainers();

    containerSize = myContainers .Sum(container => 
      container.ListBlobs(null, true).Cast<CloudBlockBlob>().Sum(blobItem => blobItem.Properties.Length));

但是,该软件包现已弃用,我已升级为使用 Azure.Storage.Blobs

我尝试使用来自here 的 ListContainers 示例,但它看起来需要 C# 8:

async static Task ListContainers(BlobServiceClient blobServiceClient, 
                                string prefix, 
                                int? segmentSize)
{
    string continuationToken = string.Empty;

    try
    {
        do
        {
            // Call the listing operation and enumerate the result segment.
            // When the continuation token is empty, the last segment has been returned
            // and execution can exit the loop.
            var resultSegment = 
                blobServiceClient.GetBlobContainersAsync(BlobContainerTraits.Metadata, prefix, default)
                .AsPages(continuationToken, segmentSize);
            await foreach (Azure.Page<BlobContainerItem> containerPage in resultSegment)
            {
                foreach (BlobContainerItem containerItem in containerPage.Values)
                {
                    Console.WriteLine("Container name: {0}", containerItem.Name);
                }

                // Get the continuation token and loop until it is empty.
                continuationToken = containerPage.ContinuationToken;

                Console.WriteLine();
            }

        } while (continuationToken != string.Empty);
    }
    catch (RequestFailedException e)
    {
        Console.WriteLine(e.Message);
        Console.ReadLine();
        throw;
    }
}

我也不确定循环遍历它是否是获取存储帐户中容器总大小的正确方法。

有人可以帮忙吗?谢谢。

【问题讨论】:

  • 据我所知,循环是您必须计算 blob 容器总大小的最佳/简单方法。如果您需要更详细的答案,请告诉我。

标签: c# azure azure-devops


【解决方案1】:

我不知道循环槽 blob 更好的方法。我修改了你给出的例子

wchich 在 C# 8.0 中工作

async static Task<Dictionary<string, long>> ListContainers(BlobServiceClient blobServiceClient,
                                        string connectionString,
                                        string prefix,
                                        int? segmentSize)
{
    string continuationToken = string.Empty;
    var sizes = new Dictionary<string, long>();
    try
    {

        do
        {
            // Call the listing operation and enumerate the result segment.
            // When the continuation token is empty, the last segment has been returned
            // and execution can exit the loop.
            var resultSegment =
                blobServiceClient.GetBlobContainersAsync(BlobContainerTraits.Metadata, prefix, default)
                .AsPages(continuationToken, segmentSize);
            await foreach (Azure.Page<BlobContainerItem> containerPage in resultSegment)
            {

                foreach (BlobContainerItem containerItem in containerPage.Values)
                {
                    BlobContainerClient container = new BlobContainerClient(connectionString, containerItem.Name);

                    var size = container.GetBlobs().Sum(b => b.Properties.ContentLength.GetValueOrDefault());

                    sizes.Add(containerItem.Name, size);

                    Console.WriteLine("Container name: {0} size: {1}", containerItem.Name.PadRight(30), size);
                }

                // Get the continuation token and loop until it is empty.
                continuationToken = containerPage.ContinuationToken;

                Console.WriteLine();
            }

        } while (continuationToken != string.Empty);

        return sizes;
    }
    catch (RequestFailedException e)
    {
        Console.WriteLine(e.Message);
        Console.ReadLine();
        throw;
    }
}

这个适用于 C# 7.x(要编译,您只需要 ToListAsync() 方法,它位于 System.Linq.Async NuGet 包中。)

async static Task<Dictionary<string, long>> ListContainers(BlobServiceClient blobServiceClient,
                                        string connectionString,
                                        string prefix,
                                        int? segmentSize)
        {
            string continuationToken = string.Empty;
            var sizes = new Dictionary<string, long>();
            try
            {

                do
                {
                    // Call the listing operation and enumerate the result segment.
                    // When the continuation token is empty, the last segment has been returned
                    // and execution can exit the loop.
                    var resultSegment =
                        await blobServiceClient.GetBlobContainersAsync(BlobContainerTraits.Metadata, prefix, default)
                        .AsPages(continuationToken, segmentSize).ToListAsync();
                     foreach (Azure.Page<BlobContainerItem> containerPage in resultSegment)
                    {

                        foreach (BlobContainerItem containerItem in containerPage.Values)
                        {
                            BlobContainerClient container = new BlobContainerClient(connectionString, containerItem.Name);

                            var size = container.GetBlobs().Sum(b => b.Properties.ContentLength.GetValueOrDefault());

                            sizes.Add(containerItem.Name, size);

                            Console.WriteLine("Container name: {0} size: {1}", containerItem.Name.PadRight(30), size);
                        }

                        // Get the continuation token and loop until it is empty.
                        continuationToken = containerPage.ContinuationToken;

                        Console.WriteLine();
                    }

                } while (continuationToken != string.Empty);

                return sizes;
            }
            catch (RequestFailedException e)
            {
                Console.WriteLine(e.Message);
                Console.ReadLine();
                throw;
            }
        }

我刚刚使用这些包为 .NET 4.8 运行了这段代码:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Azure.Core" version="1.4.1" targetFramework="net48" />
  <package id="Azure.Storage.Blobs" version="12.6.0" targetFramework="net48" />
  <package id="Azure.Storage.Common" version="12.5.2" targetFramework="net48" />
  <package id="Microsoft.Bcl.AsyncInterfaces" version="1.1.0" targetFramework="net48" />
  <package id="System.Buffers" version="4.5.0" targetFramework="net48" />
  <package id="System.Diagnostics.DiagnosticSource" version="4.6.0" targetFramework="net48" />
  <package id="System.Linq.Async" version="4.1.1" targetFramework="net48" />
  <package id="System.Memory" version="4.5.3" targetFramework="net48" />
  <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
  <package id="System.Runtime.CompilerServices.Unsafe" version="4.6.0" targetFramework="net48" />
  <package id="System.Text.Encodings.Web" version="4.6.0" targetFramework="net48" />
  <package id="System.Text.Json" version="4.6.0" targetFramework="net48" />
  <package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net48" />
  <package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
</packages>

一切都很好。

【讨论】:

  • 感谢您的回复,也很抱歉,我应该更准确。是等待 foreach(resultSegment 中的 Azure.Page containerPage)告诉我我需要 C# 8。
  • 再次感谢,但仍有问题。 ToListAsync 和 Azure.Page 下方有红色波浪线,表示找不到它们。我的项目的 .net 框架是 4.8。
  • 我在 .NET 4.8 上运行它没有任何问题。
  • 很奇怪。我有所有这些包,我的版本要么相等,要么更高。我什至使用 csc -langversion:? 检查了我的默认 C#命令,它告诉我我正在使用 C# 8。错误一直说您缺少该 ToListAsync 的程序集引用或 Using 语句。完全糊涂了。 :)
  • 您是否尝试过创建全新的项目?你清理你的解决方案了吗?我在 dotnet core 3.1 (C#) 和 dotnet core 2.x 和 dotnet framework 4.8 (C# 7.x) 上面运行 sn-ps 没有任何问题。
猜你喜欢
  • 2019-03-08
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 2016-03-28
相关资源
最近更新 更多