获取 Azure 存储容器中 blob 数量的最有效方法是什么?
现在我想不出除了下面的代码之外的任何方法:
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();
获取 Azure 存储容器中 blob 数量的最有效方法是什么?
现在我想不出除了下面的代码之外的任何方法:
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();
如果您只想知道容器中有多少 Blob 而无需编写代码,您可以使用Microsoft Azure Storage Explorer 应用程序。
我尝试使用 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 的情况下被修改,这将强制重新计数)但它并不可靠。
API 不包含容器计数方法或属性,因此您需要执行与您发布的内容类似的操作。但是,如果返回的项目超过 5,000 个(或者如果您指定要返回的最大 # 并且列表超过该数量),则需要处理 NextMarker。然后,您将根据 NextMarker 进行 add'l 调用并添加计数。
编辑:每 smarx:SDK 应该为您处理 NextMarker。如果您在 API 级别工作,则需要处理 NextMarker,通过 REST调用List Blob 。
或者,如果您正在控制 blob 插入/删除(例如,通过 wcf 服务),则可以使用 blob 容器的元数据区域来存储您在每次插入或删除时计算的缓存容器计数。您只需要处理对容器的写入并发。
使用 PHP API 和 getNextMarker 的示例。
计算 Azure 容器中的 Blob 总数。这需要很长时间:100000 个 blob 大约需要 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;
如果您不使用虚拟目录,则以下内容将按照之前的回答进行。
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();
但是,如果您使用虚拟目录,上面的代码片段可能没有所需的计数。
例如,如果您的 blob 存储类似于以下内容: /container/directory/filename.txt 其中 blob name = directory/filename.txt container.ListBlobs().Count(); 只会计算你有多少“/directory”虚拟目录。如果要列出虚拟目录中包含的 blob,则需要在 ListBlobs() 调用中设置 useFlatBlobListing = true。
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs(null, true).Count();
注意:使用 useFlatBlobListing = true 的 ListBlobs() 调用是一个更昂贵/更慢的调用......
使用Azure Storage 的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
另一个 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)
我花了相当长的时间来找到以下解决方案 - 我不想像我这样的人浪费时间 - 所以即使在 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());
}
}
}
牢记其他答案中的所有性能问题,这里是Azure SDK v12IAsyncEnnumerable
的版本,它利用. 这需要对System.Linq.Async的包引用。
public async Task<int> GetBlobCount()
{
var container = await GetBlobContainerClient();
var blobsPaged = container.GetBlobsAsync();
return await blobsPaged
.AsAsyncEnumerable()
.CountAsync();
}
计算经典和新 blob 存储帐户中的所有 blob。该解决方案基于@gandikota-saiikoushik,适用于具有大量 blob 的 blob 容器。
//setup set values from Azure Portal
var accountName = "<ACCOUNTNAME>";
var accountKey = "<ACCOUTNKEY>";
var containerName = "<CONTAINTERNAME>";
uristr = $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey}";
var storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(uristr);
var client = storageAccount.CreateCloudBlobClient();
var container = client.GetContainerReference(containerName);
BlobContinuationToken continuationToken = new BlobContinuationToken();
blobcount = CountBlobs(container, continuationToken).ConfigureAwait(false).GetAwaiter().GetResult();
Console.WriteLine($"blobcount:{blobcount}");
public static async Task<int> CountBlobs(CloudBlobContainer container, BlobContinuationToken currentToken)
{
BlobContinuationToken continuationToken = null;
var result = 0;
do
{
var response = await container.ListBlobsSegmentedAsync(continuationToken);
continuationToken = response.ContinuationToken;
result += response.Results.Count();
}
while (continuationToken != null);
return result;
}