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

后端 未结 3 2144
长发绾君心
长发绾君心 2021-02-07 02:53

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 col

相关标签:
3条回答
  • 2021-02-07 03:36

    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);
    }
    
    0 讨论(0)
  • 2021-02-07 03:45

    The previous answers are good. I just wanted to point out 2 things:

    1) Nowadays ASYNC programming is recommended to do and supported by Azure SDK as well. So try to use it:

    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) Fetching Metadata in a separate call is not efficient. The code makes 2 HTTP request per blob object. ListBlobs() method supports getting Metadata with as well in one call by setting BlobListingDetails parameter:

    CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
    var blobs = dir.ListBlobs(useFlatBlobListing: true, blobListingDetails: BlobListingDetails.Metadata);
    

    I recommend to use second code it it is possible. Since it is the most efficient way to fetch Metadata.

    0 讨论(0)
  • 2021-02-07 03:46

    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.

    0 讨论(0)
提交回复
热议问题