【问题标题】:Azure Storage container sizeAzure 存储容器大小
【发布时间】:2012-12-31 20:05:49
【问题描述】:

如何在 Azure 存储中获取容器的大小?我通过 C# API 访问 Azure 存储:

var account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["AzureStoragePrimary"]);
var client = account.CreateCloudBlobClient();
var container = client.GetContainerReference("myContainer");

【问题讨论】:

  • 您确定您使用的是 C# 吗? var account?

标签: c# azure azure-storage


【解决方案1】:

12.6.0 版本中使用Azure.Storage.Blobs 可以这样完成:

static void Main(string[] args)
{

    BlobServiceClient client = new BlobServiceClient(connectionString);

    GetContainersSize(client, connectionString, null, null).Wait();
}

//-------------------------------------------------
// List containers
//-------------------------------------------------
async static Task<ConcurrentDictionary<string, long>> GetContainersSize(BlobServiceClient blobServiceClient,
                                string connectionString,
                                string prefix,
                                int? segmentSize)
{
    string continuationToken = string.Empty;
    var sizes = new ConcurrentDictionary<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 blobs = container.GetBlobsAsync().AsPages(continuationToken);

                    await foreach(var blobPage in blobs)
                    {
                        var blobPageSize = blobPage.Values.Sum(b => b.Properties.ContentLength.GetValueOrDefault());
                        sizes.AddOrUpdate(containerItem.Name, blobPageSize, (key, currentSize) => currentSize + blobPageSize);
                    }
                }

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

        } while (continuationToken != string.Empty);

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

【讨论】:

  • 感谢 sn-p。在 C# >= 7.1 上,您可以使用 async Task Main 并将 .Wait() 替换为 await
【解决方案2】:

针对 .NET Core 2,ListBlobs 方法不可用,因为您只能访问异步方法。

因此您可以使用 ListBlobsSegmentedAsync 方法获取 Azure 存储容器大小

BlobContinuationToken continuationToken = null;
long totalBytes = 0;
do
{
    var response = await container.ListBlobsSegmentedAsync(continuationToken);
    continuationToken = response.ContinuationToken;
    totalBytes += response.Results.OfType<CloudBlockBlob>().Sum(s => s.Properties.Length);
} while (continuationToken != null);

【讨论】:

    【解决方案3】:

    可能更完整的方法。关键区别在于 listblobs() 调用中的第二个参数,它强制执行平面列表:

    public class StorageReport
    {
        public int FileCount { get; set; }
        public int DirectoryCount { get; set; }
        public long TotalBytes { get; set; }
    }
    
    //embdeded in some method
    StorageReport report = new StorageReport() { 
        FileCount = 0,
        DirectoryCount = 0,
        TotalBytes = 0
    };
    
    
    foreach (IListBlobItem blobItem in container.ListBlobs(null, true, BlobListingDetails.None))
    {
        if (blobItem is CloudBlockBlob)
        {
            CloudBlockBlob blob = blobItem as CloudBlockBlob;
            report.FileCount++;
            report.TotalBytes += blob.Properties.Length;
        }
        else if (blobItem is CloudPageBlob)
        {
            CloudPageBlob pageBlob = blobItem as CloudPageBlob;
    
            report.FileCount++;
            report.TotalBytes += pageBlob.Properties.Length;
        }
        else if (blobItem is CloudBlobDirectory)
        {
            CloudBlobDirectory directory = blobItem as CloudBlobDirectory;
    
            report.DirectoryCount++;
        }                        
    }
    

    【讨论】:

    • 这太棒了!它在超过 6TB 的数据和数百万个文件中发挥了作用
    • @ElliotWood 这太疯狂了!很高兴它站起来了。
    【解决方案4】:
    CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["AzureStoragePrimary"]);
    CloudBlobClient blobClient = account.CreateCloudBlobClient();
    CloudBlobContainer blobContainer = blobClient.GetContainerReference("myContainer");
    int fileSize = 0;
    foreach (var blobItem in blobContainer.ListBlobs())
    {
        fileSize += blobItem.Properties.Length;
    } 
    

    fileSize 包含容器的大小,即包含的 blob(文件)的总大小。

    参考:CloudBlob:http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.cloudblob_methods.aspx

    【讨论】:

    • 这个long size = 0; foreach (var blob in container.ListBlobs()) { size += container.GetBlobReference(blob.Uri.AbsoluteUri).Properties.Length; }总是返回0。
    【解决方案5】:

    我已将 Microsoft.WindowsAzure.StorageClient.dll 1.1.0.0 从 Windows Azure SDK 更新为 Microsoft.WindowsAzure.Storage.dll 2.0.0.0 从 Windows Azure 存储 NuGet 包,它现在可以工作了。

    long size = 0;
    var list = container.ListBlobs();
    foreach (CloudBlockBlob blob in list) {
        size += blob.Properties.Length;
    }
    

    【讨论】:

    • 什么值返回? KB? mb?
    • 一个长值,包含容器的大小(以字节为单位)。
    猜你喜欢
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    相关资源
    最近更新 更多