2010-04-15 96 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. 
     }