2014-10-11 43 views
0

在一種情況下,我需要加載數百個Azure blob,但不確定它們是否存在。打開塊blob(如果存在)

此代碼執行2次往返於服務器 - 在Exists一個HEAD和一個GETOpenRead

CloudBlobContainer container = ... ; 
Parallel.ForEach(... => { 
    string blobName = ... ; 
    var blob = container.GetBlockBlobReference(blobName); 
    if (blob.Exists()) { 
     using (var stream = blob.OpenRead()) { 
      ... 
     } 
    } 
}); 

... ...可能

  • 打開BLOB
  • 如果不存在則不會拋出異常
  • 一次往返服務器

...?

+0

難道你不能只打開它並捕捉異常? – 2014-10-11 12:27:50

+0

在調試過程中(在這種情況下),在性能和煩人方面的例外是昂貴的。 – 2014-10-11 12:30:50

+0

也許不是一種適用於您的解決方案,但您可以使用['DebuggerNonUserCode'](http://stackoverflow.com/questions/2738115/can-i-enable-disable-breaking-on-exceptions-programatically)屬性的代碼涉及臨時禁用中斷的例外。 – 2014-10-11 12:44:45

回答

0

不,這是不可能的。最好的方法是不要調用Exists並改爲捕獲異常。如果您擔心性能,請注意即使使用Exists調用,System.Net也會拋出異常。然而,Azure存儲客戶端庫通過向調用者返回false來捕獲並處理它。

1

您可以使用一次性命中獲取容器中的所有Blob,然後在檢索Blob前檢查該列表。下面是改編自東西我用返回您可以使用快速列表查找一個HashSet的方法:

/// <summary> 
/// Get the names of all blobs in a container and optionally containers with a 
/// specific prefix. 
/// </summary> 
/// <param name="container">Name of Container to search</param> 
/// <param name="prefix">Further filter where to search in container with a prefix.</param> 
/// <returns>HashSet of string that names all blobs in container</returns> 
public HashSet<string> GetBlobsInContainer(string container, string prefix) 
{ 
    HashSet<string> theBlobs = new HashSet<string>(); 

    //GetStorageAcct returns CloudStorageAccount object 
    CloudBlobClient blobClient = GetStorageAcct().CreateCloudBlobClient(); 
    CloudBlobContainer blobContainer = blobClient.GetContainerReference(container); 

    foreach (IListBlobItem item in blobContainer.ListBlobs(prefix, true)) 
    { 
    CloudBlockBlob cbb = (CloudBlockBlob)item; 
    theBlobs.Add(cbb.Name); 
    } 

    return theBlobs; 
} 
+0

這很有用,但有數十萬個斑點。需要很長時間才能閱讀全部內容,並且'HashSet '會消耗大量內存。 – 2014-10-11 13:28:43

相關問題