我正在使用Microsoft Azure .NET客户端库与Azure云存储进行交互。我需要能够访问其元数据集合中每个blob的其他信息。我目前正在使用CloudBlobDirectory.ListBlobs()方法获取我在blob名称中设计的目录结构的特定目录中的blob列表。 ListBlobs()方法返回IListBlobItem对象的列表。它们只有几个属性:Url以及对父目录和父容器的引用。我需要获取实际blob对象的元数据。
我设想有一种方法可以将IListBlobItem强制转换为BlockBlob对象,或者使用IListBlockItem来获取对BlockBlob的引用,但似乎找不到这样做的方法。
我的问题是:有没有办法从这个方法中获取BlockBlob对象,还是我必须使用不同的方法来获取实际的BlockBlob对象?如果不同,那么你可以建议一种方法来实现这一点,同时还能够通过“目录”方案进行过滤吗?
答案 0 :(得分:17)
好的......我找到了一种方法来做到这一点,虽然看起来有点笨拙和间接,但它确实实现了我认为应该可行的主要内容,即将IListBlobItem直接转换为CloudBlockBlob对象。
我正在做的是从Directory对象的ListBlobs()方法获取列表,然后循环遍历列表中的每个项目并将项目转换为CloudBlockBlob对象,然后调用FetchAttributes()方法来检索属性(包括元数据)。然后添加一个新的"信息"反对新的信息对象列表。以下是我使用的代码:
CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
var blobs = dir.ListBlobs(true);
foreach (IListBlobItem item in blobs)
{
CloudBlockBlob blob = (CloudBlockBlob)item;
blob.FetchAttributes();
files.Add(new ImageInfo
{
FileUrl = item.Uri.ToString(),
FileName = item.Uri.PathAndQuery.Replace(restaurantId.ToString().PadLeft(3, '0') + "/", ""),
ImageName = blob.Metadata["Name"]
});
}
整个" Blob"概念似乎不必要地复杂,并且似乎没有达到我认为可能是Blob包装器的主要特征之一。也就是说,通过允许对名称,目录,容器和元数据进行查询来扩展搜索功能的方法。我以为你可以构建一个linq查询,它有点像:"返回'图像中所有blob的列表。容器,在自然/风景/'元数据键为' category'的目录路径具有'夕阳'"的价值。似乎没有办法做到这一点,这似乎是错过了我的机会。哦,好吧。
如果我错了,请离开这里,请告诉我。
答案 1 :(得分:3)
这种方法是为 Java 开发的,但我希望它能以某种方式被修改以适应任何其他支持的编程语言。尽管您要求的功能尚未明确开发,但我认为我发现了一种从CloudBlockBlob
元素访问ListBlobItem
数据的不同(希望不那么笨拙)的方式。
以下代码可用于删除具体目录中的每个blob。
String blobUri;
CloudBlobClient blobClient = /* Obtain your blob client */
try{
CloudBlobContainer container = /* Obtain your blob container */
for (ListBlobItem blobItem : container.listBlobs(blobPrefix)) {
if (blobItem instanceof CloudBlob) {
blob = (CloudBlob) blobItem;
if (blob.exists()){
System.out.println("Deleting blob " + blob.getName());
blob.delete();
}
}
}
}catch (URISyntaxException | StorageException ex){
Logger.getLogger(BlobOperations.class.getName()).log(Level.SEVERE, null, ex);
}
答案 2 :(得分:2)
以前的答案是好的。我只想指出两点:
1)建议现在使用ASYNC编程,并且Azure SDK也支持该编程。因此,请尝试使用它:
CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
var blobs = dir.ListBlobs(true);
foreach (IListBlobItem item in blobs)
{
CloudBlockBlob blob = (CloudBlockBlob)item;
await blob.FetchAttributesAsync(); //Use async calls...
}
2)在单独的调用中获取元数据效率不高。该代码为每个blob对象发出2个HTTP请求。 ListBlobs()方法支持通过设置BlobListingDetails参数在一次调用中获取元数据:
CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
var blobs = dir.ListBlobs(useFlatBlobListing: true, blobListingDetails: BlobListingDetails.Metadata);
我建议使用第二个代码,这是可能的。因为这是获取元数据的最有效方法。