在Azure存储容器中获取blob计数

时间:2011-07-28 15:49:54

标签: azure azure-storage azure-storage-blobs

获取Azure存储容器中Blob数量的最有效方法是什么?

现在除了以下代码之外,我想不出任何其他方式:

CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();

9 个答案:

答案 0 :(得分:14)

如果您只想知道容器中有多少blob而不编写代码,可以使用Microsoft Azure Storage Explorer application

  1. 打开所需的BlobContainer enter image description here
  2. 单击“文件夹统计信息”图标 enter image description here
  3. 在“活动”窗口中观察blob的计数 enter image description here

答案 1 :(得分:12)

我尝试使用ListBlobs()对blob进行计数,对于一个包含大约400,000个项目的容器,我花了5分多钟。

如果您可以完全控制容器(即控制何时发生写入),则可以在容器元数据中缓存大小信息,并在每次删除或插入项目时更新它。这是一段将返回容器blob计数的代码:

static int CountBlobs(string storageAccount, string containerId)
{
    CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(storageAccount);
    CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
    CloudBlobContainer cloudBlobContainer = blobClient.GetContainerReference(containerId);

    cloudBlobContainer.FetchAttributes();

    string count = cloudBlobContainer.Metadata["ItemCount"];
    string countUpdateTime = cloudBlobContainer.Metadata["CountUpdateTime"];

    bool recountNeeded = false;

    if (String.IsNullOrEmpty(count) || String.IsNullOrEmpty(countUpdateTime))
    {
        recountNeeded = true;
    }
    else
    {
        DateTime dateTime = new DateTime(long.Parse(countUpdateTime));

        // Are we close to the last modified time?
        if (Math.Abs(dateTime.Subtract(cloudBlobContainer.Properties.LastModifiedUtc).TotalSeconds) > 5) {
            recountNeeded = true;
        }
    }

    int blobCount;
    if (recountNeeded)
    {
        blobCount = 0;
        BlobRequestOptions options = new BlobRequestOptions();
        options.BlobListingDetails = BlobListingDetails.Metadata;

        foreach (IListBlobItem item in cloudBlobContainer.ListBlobs(options))
        {
            blobCount++;
        }

        cloudBlobContainer.Metadata.Set("ItemCount", blobCount.ToString());
        cloudBlobContainer.Metadata.Set("CountUpdateTime", DateTime.Now.Ticks.ToString());
        cloudBlobContainer.SetMetadata();
    }
    else
    {
        blobCount = int.Parse(count);
    }

    return blobCount;
}

当然,这假定您每次修改容器时都更新ItemCount / CountUpdateTime。 CountUpdateTime是一种启发式安全措施(如果容器确实在没有人更新CountUpdateTime的情况下进行了修改,这将强制重新计算)但是它不可靠。

答案 2 :(得分:11)

API不包含容器计数方法或属性,因此您需要执行类似于发布的操作。但是,如果超过5,000个项目返回(或者如果指定max#返回且列表超过该数量),则需要处理NextMarker。然后你将根据NextMarker进行add'l调用并添加计数。

编辑:Per smarx:SDK应该为您处理NextMarker。如果您在API级别工作,通过REST调用List Blobs,则需要处理NextMarker。

或者,如果您正在控制blob插入/删除(例如,通过wcf服务),则可以使用blob容器的元数据区域来存储每次插入或删除时计算的缓存容器计数。你只需要处理容器的写并发。

答案 3 :(得分:2)

使用PHP API和getNextMarker的示例。

计算Azure容器中blob的总数。 这需要很长时间:100000个斑点大约需要30秒。

(假设我们有一个有效的$ connectionString和$ container_name)

$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);
$opts = new ListBlobsOptions();
$nblobs = 0;

while($cont) {

  $blob_list = $blobRestProxy->listBlobs($container_name, $opts);      

  $nblobs += count($blob_list->getBlobs());

  $nextMarker = $blob_list->getNextMarker();

  if (!$nextMarker || strlen($nextMarker) == 0) $cont = false;
  else $opts->setMarker($nextMarker);
}
echo $nblobs;

答案 4 :(得分:2)

如果您没有使用虚拟目录,以下内容将按照之前的说法进行操作。

CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();

但是,如果您使用的是虚拟目录,则上面的代码段可能没有所需的计数。

例如,如果blob的存储类似于以下内容:/container/directory/filename.txt其中blob name = directory / filename.txt,container.ListBlobs()。Count();只计算多少" /目录"你有的虚拟目录。如果要列出虚拟目录中包含的blob,则需要在ListBlobs()调用中设置useFlatBlobListing = true。

CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs(null, true).Count();

注意:使用useFlatBlobListing = true的ListBlobs()调用是一个更加昂贵/缓慢的调用......

答案 5 :(得分:1)

使用Azure存储的 Python API ,它就像:

from azure.storage import *
blob_service = BlobService(account_name='myaccount', account_key='mykey')
blobs = blob_service.list_blobs('mycontainer')
len(blobs)  #returns the number of blob in a container

答案 6 :(得分:0)

另一个Python示例,运行缓慢,但可以正确处理> 5000个文件:

from azure.storage.blob import BlobServiceClient

constr="Connection string"
container="Container name"

blob_service_client = BlobServiceClient.from_connection_string(constr)
container_client = blob_service_client.get_container_client(container)
blobs_list = container_client.list_blobs()

num = 0
size = 0
for blob in blobs_list:
    num += 1
    size += blob.size
    print(blob.name,blob.size)

print("Count: ", num)
print("Size: ", size)

答案 7 :(得分:0)

我花了相当长的时间找到以下解决方案-我不想像我这样的人浪费时间-因此即使在9年后也要在这里回复

package com.sai.koushik.gandikota.test.app;

import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.blob.*;


public class AzureBlobStorageUtils {


    public static void main(String[] args) throws Exception {
        AzureBlobStorageUtils getCount =  new AzureBlobStorageUtils();
        String storageConn = "<StorageAccountConnection>";
        String blobContainerName = "<containerName>";
        String subContainer =  "<subContainerName>";
        Integer fileContainerCount = getCount.getFileCountInSpecificBlobContainersSubContainer(storageConn,blobContainerName, subContainer);
        System.out.println(fileContainerCount);
    }

    public Integer getFileCountInSpecificBlobContainersSubContainer(String storageConn, String blobContainerName, String subContainer) throws Exception {
        try {
            CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConn);
            CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
            CloudBlobContainer blobContainer = blobClient.getContainerReference(blobContainerName);
            return ((CloudBlobDirectory) blobContainer.listBlobsSegmented().getResults().stream().filter(listBlobItem -> listBlobItem.getUri().toString().contains(subContainer)).findFirst().get()).listBlobsSegmented().getResults().size();
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        } 
    }

}


答案 8 :(得分:0)

考虑到其他答案中的所有性能问题,这里有一个利用 IAsyncEnnumerable 的 Azure SDK v12 版本。这需要对 System.Linq.Async 的包引用。

public async Task<int> GetBlobCount()
{
    var container = await GetBlobContainerClient();
    var blobsPaged = container.GetBlobsAsync();
    return await blobsPaged
        .AsAsyncEnumerable()
        .CountAsync();
}