我有一个非常简单的问题(我希望!)-我只想确定特定容器中是否存在斑点(具有我定义的名称)。如果确实存在,我将进行下载,如果不存在,我将进行其他操作。
我已经在Intertube上进行了一些搜索,显然以前曾经有一个称为DidExist的函数或类似的函数...但是与许多Azure API一样,它似乎不再存在(或者如果存在,则具有非常巧妙地变相的名字)。
我有一个非常简单的问题(我希望!)-我只想确定特定容器中是否存在斑点(具有我定义的名称)。如果确实存在,我将进行下载,如果不存在,我将进行其他操作。
我已经在Intertube上进行了一些搜索,显然以前曾经有一个称为DidExist的函数或类似的函数...但是与许多Azure API一样,它似乎不再存在(或者如果存在,则具有非常巧妙地变相的名字)。
Answers:
新的API具有.Exists()函数调用。只要确保您使用GetBlockBlobReference
,不会执行对服务器的调用即可。它使功能变得简单:
public static bool BlobExistsOnCloud(CloudBlobClient client,
string containerName, string key)
{
return client.GetContainerReference(containerName)
.GetBlockBlobReference(key)
.Exists();
}
len(blob_service.list_blobs(container_name, file_name)) > 0
注意:此答案已过期。请参阅Richard的答案,以一种简单的方法检查是否存在
不,您不会缺少简单的东西……我们很好地将这种方法隐藏在新的StorageClient库中。:)
我刚刚写了一篇博客文章来回答您的问题:http : //blog.smarx.com/posts/testing-existence-of-a-windows-azure-blob。
简短的答案是:使用CloudBlob.FetchAttributes(),它对Blob发出HEAD请求。
OpenRead
,则不会抛出或返回空Stream或类似的东西。当您开始从中下载文件时,只会收到错误消息。在一个地方处理所有这些要容易
如果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很简单。
如果您不喜欢使用异常方法,那么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;
}
如果您的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
使用更新的SDK,一旦有了CloudBlobReference,就可以在引用上调用Exists()。
这就是我的方法。为需要的人显示完整的代码。
// 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.
}
尽管这里的大多数答案在技术上都是正确的,但是大多数代码示例都在进行同步/阻塞调用。除非您受制于非常老的平台或代码库,否则HTTP调用应始终异步进行,在这种情况下,SDK完全支持它。只需使用ExistsAsync()
代替即可Exists()
。
bool exists = await client.GetContainerReference(containerName)
.GetBlockBlobReference(key)
.ExistsAsync();
Exists()
是同步的,因为它阻塞线程直到完成。await ExistsAscyn()
是异步的,因为它不是。两者遵循相同的逻辑流程,因为下一行代码要等到上一行完成后才开始,但这是非阻塞性质,ExistsAsync
因此使它异步。
如果您不喜欢其他解决方案,这是一个不同的解决方案:
我正在使用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;
}
}
}
希望这对以后的人有所帮助。