Mam bardzo proste pytanie (mam nadzieję!) - chcę się tylko dowiedzieć, czy w konkretnym kontenerze istnieje blob (o zdefiniowanej przeze mnie nazwie). Pobiorę go, jeśli istnieje, a jeśli nie, zrobię coś innego.
Wyszukałem trochę w intertubach i najwyraźniej była tam funkcja o nazwie DoesExist lub coś podobnego ... ale podobnie jak w przypadku wielu interfejsów API platformy Azure, wydaje się, że już jej tam nie ma (lub jeśli tak, ma bardzo sprytnie zamaskowana nazwa).
Odpowiedzi:
Nowe API ma wywołanie funkcji .Exists (). Tylko upewnij się, że używasz
GetBlockBlobReference
, który nie wykonuje wywołania do serwera. Dzięki temu funkcja jest tak prosta, jak:public static bool BlobExistsOnCloud(CloudBlobClient client, string containerName, string key) { return client.GetContainerReference(containerName) .GetBlockBlobReference(key) .Exists(); }
źródło
len(blob_service.list_blobs(container_name, file_name)) > 0
Uwaga: ta odpowiedź jest teraz nieaktualna. Zapoznaj się z odpowiedzią Richarda, aby w łatwy sposób sprawdzić istnienie
Nie, nie brakuje Ci czegoś prostego ... wykonaliśmy dobrą robotę, ukrywając tę metodę w nowej bibliotece StorageClient. :)
Właśnie napisałem post na blogu, aby odpowiedzieć na Twoje pytanie: http://blog.smarx.com/posts/testing-existence-of-a-windows-azure-blob .
Krótka odpowiedź brzmi: użyj CloudBlob.FetchAttributes (), która wykonuje żądanie HEAD względem obiektu BLOB.
źródło
OpenRead
, nie wyrzuci ani nie zwróci pustego strumienia ani niczego w tym stylu. Błędy pojawią się tylko wtedy, gdy zaczniesz z niego pobierać. Dużo łatwiej poradzić sobie z tym wszystkim w jednym miejscu :)Wydaje się kiepskie, że musisz złapać wyjątek, aby sprawdzić, czy obiekt blob istnieje.
public static bool Exists(this CloudBlob blob) { try { blob.FetchAttributes(); return true; } catch (StorageClientException e) { if (e.ErrorCode == StorageErrorCode.ResourceNotFound) { return false; } else { throw; } } }
źródło
Jeśli obiekt blob jest publiczny, możesz oczywiście po prostu wysłać żądanie HTTP HEAD - z dowolnego z milionów języków / środowisk / platform, które wiedzą, jak to zrobić - i sprawdzić odpowiedź.
Podstawowe interfejsy API platformy Azure są interfejsami HTTP opartymi na języku RESTful. Biblioteka StorageClient jest jednym z wielu możliwych opakowań wokół nich. Oto kolejny, który Sriram Krishnan zrobił w Pythonie:
http://www.sriramkrishnan.com/blog/2008/11/python-wrapper-for-windows-azure.html
Pokazuje również, jak uwierzytelniać się na poziomie HTTP.
Zrobiłem dla siebie podobną rzecz w C #, ponieważ wolę patrzeć na platformę Azure przez pryzmat HTTP / REST niż przez pryzmat biblioteki StorageClient. Od dłuższego czasu nawet nie zadałem sobie trudu, aby zaimplementować metodę ExistsBlob. Wszystkie moje obiekty blob były publiczne i zrobienie HTTP HEAD było trywialne.
źródło
Nowa biblioteka magazynu Windows Azure zawiera już metodę Exist (). Znajduje się w Microsoft.WindowsAzure.Storage.dll.
Dostępny jako pakiet NuGet
Utworzony przez: Microsoft
Id: WindowsAzure
Wersja magazynu: 2.0.5.1
Zobacz także msdn
źródło
Jeśli nie lubisz używać metody wyjątku, podstawowa wersja C # tego, co sugeruje judell, jest poniżej. Uważaj jednak, że naprawdę powinieneś poradzić sobie również z innymi możliwymi odpowiedziami.
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url); myReq.Method = "HEAD"; HttpWebResponse myResp = (HttpWebResponse)myReq.GetResponse(); if (myResp.StatusCode == HttpStatusCode.OK) { return true; } else { return false; }
źródło
Jeśli Twój obiekt BLOB jest publiczny i potrzebujesz tylko metadanych:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "HEAD"; string code = ""; try { HttpWebResponse response = (HttpWebResponse)request.GetResponse(); code = response.StatusCode.ToString(); } catch { } return code; // if "OK" blob exists
źródło
Oto inne rozwiązanie, jeśli nie lubisz innych rozwiązań:
Używam wersji 12.4.1 pakietu NuGet Azure.Storage.Blobs.
Otrzymuję Azure.Pageable przedmiot, który jest lista wszystkich bąble w pojemniku. Następnie sprawdzam, czy nazwa obiektu BlobItem jest równa właściwości Name każdego obiektu BLOB w kontenerze przy użyciu LINQ . (Jeśli wszystko jest prawidłowe, oczywiście)
using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using System.Linq; using System.Text.RegularExpressions; public class AzureBlobStorage { private BlobServiceClient _blobServiceClient; public AzureBlobStorage(string connectionString) { this.ConnectionString = connectionString; _blobServiceClient = new BlobServiceClient(this.ConnectionString); } public bool IsContainerNameValid(string name) { return Regex.IsMatch(name, "^[a-z0-9](?!.*--)[a-z0-9-]{1,61}[a-z0-9]$", RegexOptions.Singleline | RegexOptions.CultureInvariant); } public bool ContainerExists(string name) { return (IsContainerNameValid(name) ? _blobServiceClient.GetBlobContainerClient(name).Exists() : false); } public Azure.Pageable<BlobItem> GetBlobs(string containerName, string prefix = null) { try { return (ContainerExists(containerName) ? _blobServiceClient.GetBlobContainerClient(containerName).GetBlobs(BlobTraits.All, BlobStates.All, prefix, default(System.Threading.CancellationToken)) : null); } catch { throw; } } public bool BlobExists(string containerName, string blobName) { try { return (from b in GetBlobs(containerName) where b.Name == blobName select b).FirstOrDefault() != null; } catch { throw; } } }
Mam nadzieję, że pomoże to komuś w przyszłości.
źródło
Dzięki zaktualizowanemu SDK, gdy już masz CloudBlobReference, możesz wywołać Exists () w swoim odwołaniu.
Zobacz http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.blob.cloudblockblob.exists.aspx
źródło
Tak to robię. Wyświetlanie pełnego kodu dla tych, którzy go potrzebują.
// Parse the connection string and return a reference to the storage account. CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("AzureBlobConnectionString")); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Retrieve reference to a previously created container. CloudBlobContainer container = blobClient.GetContainerReference("ContainerName"); // Retrieve reference to a blob named "test.csv" CloudBlockBlob blockBlob = container.GetBlockBlobReference("test.csv"); if (blockBlob.Exists()) { //Do your logic here. }
źródło
Chociaż większość odpowiedzi tutaj jest poprawnych technicznie, większość przykładów kodu wykonuje wywołania synchroniczne / blokujące. O ile nie jesteś związany bardzo starą platformą lub bazą kodu, wywołania HTTP powinny zawsze być wykonywane asynchronicznie, a zestaw SDK w tym przypadku w pełni je obsługuje. Po prostu użyj
ExistsAsync()
zamiastExists()
.bool exists = await client.GetContainerReference(containerName) .GetBlockBlobReference(key) .ExistsAsync();
źródło
Exists()
jest synchroniczny, ponieważ blokuje wątek aż do zakończenia.await ExistsAscyn()
jest asynchroniczny w tym sensie, że nie. Oba podążają za tym samym logicznym przepływem, ponieważ następny wiersz kodu nie zaczyna się, dopóki poprzedni nie zostanie ukończony, ale to nieblokujący charakterExistsAsync
sprawia, że jest on asynchroniczny.Dzięki bibliotece Azure Blob Storage w wersji 12 możesz używać platformy
BlobBaseClient.Exists()/BlobBaseClient.ExistsAsync()
Odpowiedział na inne podobne pytanie: https://stackoverflow.com/a/63293998/4865541
źródło
Wersja Java do tego samego (przy użyciu nowego zestawu SDK v12)
Wykorzystuje to autoryzację Shared Key Credential, która jest kluczem dostępu do konta.
StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey); String endpoint = String.format(Locale.ROOT, "https://%s.blob.core.windows.net", accountName); BlobServiceClient storageClient = new BlobServiceClientBuilder().credential(credential) .endpoint(endpoint).buildClient(); BlobContainerClient container = storageClient.getBlobContainerClient(containerName) if ( container.exists() ) { // perform operation when container exists }
źródło