检查Azure存储中是否存在Blob

时间:2010-04-15 05:23:55

标签: c# azure azure-blob-storage

我有一个非常简单的问题(我希望!) - 我只想知道特定容器中是否存在blob(具有我定义的名称)。如果确实存在,我会下载它,如果没有,那么我会做其他事情。

我已经对intertubes进行了一些搜索,显然曾经有一个名为DoesExist的函数或类似的东西......但是就像许多Azure API一样,这似乎不再存在(或者如果它是,有一个非常巧妙伪装的名字)。

13 个答案:

答案 0 :(得分:187)

新API具有.Exists()函数调用。只需确保使用GetBlockBlobReference,它不会执行对服务器的调用。它使功能像以下一样简单:

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

答案 1 :(得分:49)

注意:此答案现已过时。请参阅理查德的答案,以便检查存在的简便方法

不,你不会错过一些简单的东西......我们很好地将这个方法隐藏在新的StorageClient库中。 :)

我刚写了一篇博文来回答你的问题:http://blog.smarx.com/posts/testing-existence-of-a-windows-azure-blob

简短的回答是:使用CloudBlob.FetchAttributes(),它对blob执行HEAD请求。

答案 2 :(得分:16)

看起来很蹩脚,你需要捕获一个异常来测试blob是否存在。

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

答案 3 :(得分:9)

如果blob是公共的,你当然可以发送一个HTTP HEAD请求 - 来自任何知道如何做的数十种语言/环境/平台 - 并检查响应。

核心Azure API是基于REST的XML的HTTP接口。 StorageClient库是围绕它们的许多可能包装器之一。这是Sriram Krishnan在Python中做的另一个:

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

它还显示了如何在HTTP级别进行身份验证。

我在C#中为自己做了类似的事情,因为我更喜欢通过HTTP / REST镜头而不是通过StorageClient库的镜头看到Azure。很长一段时间,我甚至都不愿意实施ExistsBlob方法。我的所有blob都是公开的,做HTTP HEAD是微不足道的。

答案 4 :(得分:5)

新的Windows Azure存储库已包含Exist()方法。 它位于Microsoft.WindowsAzure.Storage.dll。

作为NuGet包提供
创建者:Microsoft
Id:WindowsAzure.Storage
版本:2.0.5.1

See also msdn

答案 5 :(得分:2)

如果你不喜欢使用异常方法,那么judell建议的基本c#版本如下。请注意,你真的应该处理其他可能的反应。

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

答案 6 :(得分:2)

如果您不喜欢其他解决方案,那么这里是另一种解决方案:

我正在使用Azure.Storage.Blobs NuGet软件包的12.4.1版本。

我得到一个 Azure.Pageable 对象,该对象是容器中所有blob的列表。然后,我检查 BlobItem 的名称是否等于容器内每个Blob的 Name 属性,利用< strong> LINQ 。 (当然,如果一切都有效)

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

希望这对以后的人有所帮助。

答案 7 :(得分:1)

使用更新的SDK,一旦您拥有CloudBlobReference,您就可以在引用上调用Exists()。

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

答案 8 :(得分:1)

这就是我这样做的方式。显示需要它的人的完整代码。

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

答案 9 :(得分:1)

尽管这里的大多数答案在技术上都是正确的,但大多数代码示例仍在进行同步/阻塞调用。除非您受制于非常老的平台或代码库,否则HTTP调用应该始终异步进行,并且在这种情况下,SDK完全支持它。只需使用ExistsAsync()而不是Exists()

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

答案 10 :(得分:0)

如果您的Blob是公开的,您只需要元数据:

        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

答案 11 :(得分:0)

借助Azure Blob存储库v12,您可以使用BlobBaseClient.Exists()/BlobBaseClient.ExistsAsync()

回答了另一个类似的问题:https://stackoverflow.com/a/63293998/4865541

答案 12 :(得分:0)

相同的Java版本(使用新的v12 SDK)

这使用共享密钥凭据授权,即帐户访问密钥。

    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 
    }