获取Azure存储容器中Blob数量的最有效方法是什么?
现在除了以下代码之外,我想不出任何其他方式:
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();
答案 0 :(得分:14)
如果您只想知道容器中有多少blob而不编写代码,可以使用Microsoft Azure Storage Explorer application。
答案 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();
}