Как получить ссылки на объекты BlockBlob из CloudBlobDirectory.ListBlobs?
Я использую клиентские библиотеки Microsoft Azure.NET для взаимодействия с облачным хранилищем Azure. Мне нужно иметь доступ к дополнительной информации о каждом блоке в его коллекции метаданных. В настоящее время я использую метод CloudBlobDirectory.ListBlobs(), чтобы получить список blob в определенном каталоге структуры каталога, которую я разработал в именах blob. Метод ListBlobs() возвращает список объектов IListBlobItem. У них есть только несколько свойств: Url и ссылки на родительский каталог и родительский контейнер. Мне нужно добраться до метаданных фактических объектов blob.
Я предполагал, что был бы способ либо передать IListBlobItem в объект BlockBlob, либо использовать IListBlockItem, чтобы получить ссылку на BlockBlob, но не может найти способ сделать это.
Мой вопрос: есть ли способ получить объект BlockBlob из этого метода или мне нужно использовать другой способ получения фактических объектов BlockBlob? Если отличается, то можете ли вы предложить способ достижения этого, а также возможность фильтровать по схеме "каталог"?
Ответы
Ответ 1
ОК... Я нашел способ сделать это, и, хотя он кажется немного неуклюжим и косвенным, он достигает главного, что, как я думал, должно быть выполнимым, а именно, чтобы заставить IListBlobItem напрямую облачиться в объект CloudBlockBlob.
То, что я делаю, это получить список из метода ListBlobs() объекта Directory Object, а затем перебрать каждый элемент в списке и передать объект в объект 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, который будет выглядеть примерно так: "верните список всех блоков в контейнере" images ", которые находятся в пути к каталогу" natural/landscapes/ ", в котором есть ключ метаданных ' категория" со значением "закат". Кажется, что нет способа сделать это, и это кажется упущенной возможностью для меня. О, хорошо.
Если я ошибаюсь и ухожу отсюда, пожалуйста, дайте мне знать.
Ответ 2
Этот подход был разработан для Java, но я надеюсь, что его можно каким-то образом изменить, чтобы он соответствовал любому другому поддерживаемому языку программирования. Несмотря на то, что функциональность, о которой вы просите, еще не была явно разработана, я думаю, что нашел другой (надеюсь, менее cluncky) способ доступа к данным CloudBlockBlob
из элемента ListBlobItem
.
Следующий код может использоваться для удаления, например, каждого блоба внутри конкретного каталога.
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);
}
Ответ 3
Предыдущие ответы хороши. Я просто хотел указать на две вещи:
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) Извлечение метаданных в отдельном вызове неэффективно. Код выполняет 2 HTTP-запроса на каждый объект BLOB-объекта. Метод ListBlobs() поддерживает получение метаданных с помощью одного вызова, устанавливая параметр BlobListingDetails:
CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
var blobs = dir.ListBlobs(useFlatBlobListing: true, blobListingDetails: BlobListingDetails.Metadata);
Я рекомендую использовать второй код, это возможно. Так как это самый эффективный способ получения метаданных.