Checking if a blob exists in Azure Storage

C#AzureAzure Blob-Storage

C# Problem Overview


I've got a very simple question (I hope!) - I just want to find out if a blob (with a name I've defined) exists in a particular container. I'll be downloading it if it does exist, and if it doesn't then I'll do something else.

I've done some searching on the intertubes and apparently there used to be a function called DoesExist or something similar... but as with so many of the Azure APIs, this no longer seems to be there (or if it is, has a very cleverly disguised name).

C# Solutions


Solution 1 - C#

The new API has the .Exists() function call. Just make sure that you use the GetBlockBlobReference, which doesn't perform the call to the server. It makes the function as easy as:

public static bool BlobExistsOnCloud(CloudBlobClient client, 
    string containerName, string key)
{
     return client.GetContainerReference(containerName)
                  .GetBlockBlobReference(key)
                  .Exists();  
}

Solution 2 - C#

Note: This answer is out of date now. Please see Richard's answer for an easy way to check for existence

No, you're not missing something simple... we did a good job of hiding this method in the new StorageClient library. :)

I just wrote a blog post to answer your question: http://blog.smarx.com/posts/testing-existence-of-a-windows-azure-blob.

The short answer is: use CloudBlob.FetchAttributes(), which does a HEAD request against the blob.

Solution 3 - C#

Seem lame that you need to catch an exception to test it the blob exists.

public static bool Exists(this CloudBlob blob)
{
    try
    {
        blob.FetchAttributes();
        return true;
    }
    catch (StorageClientException e)
    {
        if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
        {
            return false;
        }
        else
        {
            throw;
        }
    }
}

Solution 4 - C#

If the blob is public you can, of course, just send an HTTP HEAD request -- from any of the zillions of languages/environments/platforms that know how do that -- and check the response.

The core Azure APIs are RESTful XML-based HTTP interfaces. The StorageClient library is one of many possible wrappers around them. Here's another that Sriram Krishnan did in Python:

http://www.sriramkrishnan.com/blog/2008/11/python-wrapper-for-windows-azure.html

It also shows how to authenticate at the HTTP level.

I've done a similar thing for myself in C#, because I prefer to see Azure through the lens of HTTP/REST rather than through the lens of the StorageClient library. For quite a while I hadn't even bothered to implement an ExistsBlob method. All my blobs were public, and it was trivial to do HTTP HEAD.

Solution 5 - C#

The new Windows Azure Storage Library already contains the Exist() method. It´s in the Microsoft.WindowsAzure.Storage.dll.

Available as NuGet Package
Created by: Microsoft
Id: WindowsAzure.Storage
Version: 2.0.5.1

See also msdn

Solution 6 - C#

This is the way I do it. Showing full code for those who need it.

        // 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.
        }

Solution 7 - C#

Here's a different solution if you don't like the other solutions:

I am using version 12.4.1 of the Azure.Storage.Blobs NuGet Package.

I get an Azure.Pageable object which is a list of all of the blobs in a container. I then check if the name of the BlobItem equals to the Name property of each blob inside the container utilizing LINQ. (If everything is valid, of course)

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;
        }
    }
}

Hopefully this helps someone in the future.

Solution 8 - C#

If you don't like using the exception method then the basic c# version of what judell suggests is below. Beware though that you really ought to handle other possible responses too.

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Method = "HEAD";
HttpWebResponse myResp = (HttpWebResponse)myReq.GetResponse();
if (myResp.StatusCode == HttpStatusCode.OK)
{
    return true;
}
else
{
    return false;
}

Solution 9 - C#

If your blob is public and you need just metadata:

        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

Solution 10 - C#

With the updated SDK, once you have the CloudBlobReference you can call Exists() on your reference.

See http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.blob.cloudblockblob.exists.aspx

Solution 11 - C#

Although most answers here are technically correct, most code samples are making synchronous/blocking calls. Unless you're bound by a very old platform or code base, HTTP calls should always be done asynchonously, and the SDK fully supports it in this case. Just use ExistsAsync() instead of Exists().

bool exists = await client.GetContainerReference(containerName)
    .GetBlockBlobReference(key)
    .ExistsAsync();

Solution 12 - C#

With Azure Blob storage library v12, you can use BlobBaseClient.Exists()/BlobBaseClient.ExistsAsync()

Answered on another similar question: https://stackoverflow.com/a/63293998/4865541

Solution 13 - C#

Java version for the same ( using the new v12 SDK )

This uses the Shared Key Credential authorization (account access key)

public void downloadBlobIfExists(String accountName, String accountKey, String containerName, String blobName) {
    // create a storage client using creds
    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);
    BlobClient blob = container.getBlobClient(blobName);
    if (blob.exists()) {
        // download blob
    } else {
        // do something else
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohnView Question on Stackoverflow
Solution 1 - C#RichardView Answer on Stackoverflow
Solution 2 - C#user94559View Answer on Stackoverflow
Solution 3 - C#nathanwView Answer on Stackoverflow
Solution 4 - C#judellView Answer on Stackoverflow
Solution 5 - C#huhaView Answer on Stackoverflow
Solution 6 - C#ApolloView Answer on Stackoverflow
Solution 7 - C#ZaehosView Answer on Stackoverflow
Solution 8 - C#Mad PierreView Answer on Stackoverflow
Solution 9 - C#emert117View Answer on Stackoverflow
Solution 10 - C#Babak NaffasView Answer on Stackoverflow
Solution 11 - C#Todd MenierView Answer on Stackoverflow
Solution 12 - C#Jaliya UdagedaraView Answer on Stackoverflow
Solution 13 - C#Somansh ReddyView Answer on Stackoverflow