Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get references to BlockBlob objects from CloudBlobDirectory.ListBlobs?

Tags:

I am using the Microsoft Azure .NET client libraries to interact with Azure cloud storage. I need to be able to access additional information about each blob in its metadata collection. I am currently using CloudBlobDirectory.ListBlobs() method to get a list of blobs in a particular directory of a directory structure I've devised in the blob names. The ListBlobs() method returns a list of IListBlobItem objects. They only have a couple of properties: Url and references to parent directory and parent container. I need to get to the metadata of the actual blob objects.

I envisioned there would be a way to either cast the IListBlobItem to a BlockBlob object or use the IListBlockItem to get a reference to the BlockBlob, but can't seem to find a way to do that.

My question is: Is there a way to get a BlockBlob object from this method, or do I have to use a different way of getting the actual BlockBlob objects? If different, then can you suggest a way to achieve this, while also being able to filter by the "directory" scheme?

like image 501
Richard B Avatar asked Jan 10 '13 20:01

Richard B


People also ask

What is CloudBlobDirectory?

public class CloudBlobDirectory implements ListBlobItem. Represents a virtual directory of blobs, designated by a delimiter character. Containers, which are encapsulated as CloudBlobContainer objects, hold directories, and directories hold block blobs and page blobs. Directories can also contain sub-directories.


2 Answers

OK... I found a way to do this, and while it seems a little clunky and indirect, it does achieve the main thing I thought should be doable, which is to cast the IListBlobItem directly to a CloudBlockBlob object.

What I am doing is getting the list from the Directory object's ListBlobs() method and then looping over each item in the list and casting the item to a CloudBlockBlob object and then calling the FetchAttributes() method to retrieve the properties (including the metadata). Then add a new "info" object to a new list of info objects. Here's the code I'm using:

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"]
    });
}

The whole "Blob" concept seems needlessly complex and doesn't seem to achieve what I'd have thought would have been one of the main features of the Blob wrapper. That is, a way to expand search capabilities by allowing a query over name, directory, container and metadata. I'd have thought you could construct a linq query that would read somewhat like: "return a list of all blobs in the 'images' container, that are in the 'natural/landscapes/' directory path that have a metadata key of 'category' with the value of 'sunset'". There doesn't seem to be a way to do that and that seems to be a missed opportunity to me. Oh, well.

If I'm wrong and way off base here, please let me know.

like image 197
Richard B Avatar answered Sep 27 '22 18:09

Richard B


This approach has been developed for Java, but I hope it can somehow be modified to fit any other supported language. Despite the functionality you ask has not been explicitly developed yet, I think I found a different (hopefully less clunky) way to access CloudBlockBlob data from a ListBlobItem element.

The following code can be used to delete, for example, every blob inside a specific directory.

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);
}
like image 27
Mikel Urkia Avatar answered Sep 27 '22 17:09

Mikel Urkia