2010-04-15 84 views
93

我有一个非常简单的问题(我希望!) - 我只想知道在特定容器中是否存在blob(带有我定义的名称)。如果它存在,我会下载它,如果它不存在,我会做其他事情。检查Azure存储中是否存在blob

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

+0

谢谢大家。当我使用StorageClient(并且希望保持所有Azure存储访问都通过该库)时,我使用了smarx建议的FetchAttributes-and-check-for-exceptions方法。它确实感觉有点偏离,因为我不喜欢将异常作为业务逻辑的一部分抛出 - 但希望这可以在未来的StorageClient版本中修复。) – John 2010-04-18 19:52:20

回答

151

新的API有.Exists()函数调用。只要确保您使用GetBlockBlobReference,它不会执行到服务器的呼叫。它使功能一样简单:

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

+1更新的API代码。 – VMAtm 2013-06-05 11:20:13

+2

在这一点上,这是现在最好的答案。 – Co7e 2013-07-30 14:57:03

+1

是否有...一个...蟒蛇版本? – anpatel 2014-04-23 20:38:04

48

注意:此答案已经过期。请参阅Richard的答案以便检查存在的简单方法

不,您不会错过简单的事情......我们在新的StorageClient库中隐藏了这种方法做得很好。 :)

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

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

+1

FetchAttributes()花费很长时间运行(至少在开发存储中)如果文件尚未完全提交,即只包含未提交的块。 – tjrobinson 2010-08-23 15:18:18

+6

如果你打算像OP那样去取blob,为什么不尝试下载内容?如果它不存在,它将像FetchAttributes一样抛出。首先做这个检查只是一个额外的请求,或者我错过了什么? – 2010-08-27 14:17:52

+0

Marnix是一个很好的观点。如果您要下载它,只需尝试下载它。 – smarx 2010-08-27 16:22:13

7

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

核心Azure API是基于RESTful XML的HTTP接口。 StorageClient库是围绕它们的许多可能的包装之一。这里是另一种斯利拉姆克里希南在Python做:

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

它也展示了如何在HTTP级别认证。

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

15

看来你需要捕捉一个异常来测试它存在的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; 
     } 
    } 
} 
1

如果您不喜欢使用异常方法,那么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; 
} 
+3

如果有404,HttpWebRequest.GetResponse会抛出一个异常。所以我没有看到你的代码如何规避处理异常的需要? – Nitramk 2011-12-08 07:40:59

+0

公平点。似乎GetResponse()在那一刻抛出垃圾给我!我希望它会返回404,因为这是回应! – 2011-12-14 16:29:02

5

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

可作为NuGet包
创建者:微软
编号:WindowsAzure.Storage
版本:2.0.5.1

See also msdn

0

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

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