143

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

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

4

13 回答 13

221

新 API 具有 .Exists() 函数调用。只要确保您使用GetBlockBlobReference,它不会执行对服务器的调用。它使功能变得简单:

public static bool BlobExistsOnCloud(CloudBlobClient client, 
    string containerName, string key)
{
     return client.GetContainerReference(containerName)
                  .GetBlockBlobReference(key)
                  .Exists();  
}
于 2013-05-10T14:58:08.467 回答
51

注意:这个答案现在已经过时了。请参阅 Richard 的回答,了解检查是否存在的简单方法

不,您并没有遗漏一些简单的东西……我们很好地将这个方法隐藏在新的 StorageClient 库中。:)

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

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

于 2010-04-16T05:25:07.953 回答
16

你需要捕获一个异常来测试它是否存在,这似乎很蹩脚。

public static bool Exists(this CloudBlob blob)
{
    try
    {
        blob.FetchAttributes();
        return true;
    }
    catch (StorageClientException e)
    {
        if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
        {
            return false;
        }
        else
        {
            throw;
        }
    }
}
于 2010-05-04T21:10:20.707 回答
9

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

核心 Azure API 是基于 RESTful 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 很简单。

于 2010-04-17T16:49:33.203 回答
5

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

可用作 NuGet 包
创建者:Microsoft
ID:WindowsAzure.Storage
版本:2.0.5.1

另请参阅

于 2013-05-03T09:31:22.933 回答
3

我就是这样做的。为需要的人展示完整的代码。

        // 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.
        }
于 2018-02-26T14:33:02.687 回答
3

如果您不喜欢其他解决方案,这里有一个不同的解决方案:

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

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

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

希望这对将来的某人有所帮助。

于 2020-04-07T14:23:14.690 回答
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;
}
于 2011-11-18T08:49:53.803 回答
2

如果您的 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
于 2018-12-31T11:57:28.143 回答
1

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

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

于 2013-08-05T22:16:16.620 回答
1

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

bool exists = await client.GetContainerReference(containerName)
    .GetBlockBlobReference(key)
    .ExistsAsync();
于 2018-10-17T16:06:03.570 回答
-1

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

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

于 2020-08-07T01:39:02.380 回答
-1

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

这使用共享密钥凭据授权(帐户访问密钥)

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
    }
}
于 2020-09-04T08:47:30.193 回答