![](/img/trans.png)
[英]Checking if container and blob exist in Azure Blob Storage using built in Exists method
[英]Checking if a blob exists in Azure Storage
我有一个非常简单的问题(我希望!) - 我只想找出特定容器中是否存在 blob(具有我定义的名称)。 如果它确实存在,我会下载它,如果它不存在,那么我会做其他事情。
我已经对 intertubes 进行了一些搜索,显然曾经有一个名为 DoesExist 或类似的函数……但与许多 Azure API 一样,这似乎不再存在(或者如果存在,非常巧妙地伪装的名字)。
新 API 具有 .Exists() 函数调用。 只需确保您使用GetBlockBlobReference
,它不会执行对服务器的调用。 它使功能变得如此简单:
public static bool BlobExistsOnCloud(CloudBlobClient client,
string containerName, string key)
{
return client.GetContainerReference(containerName)
.GetBlockBlobReference(key)
.Exists();
}
注意:这个答案现在已经过时了。 请参阅 Richard 的回答,了解检查是否存在的简单方法
不,您并没有遗漏一些简单的东西……我们很好地将这个方法隐藏在新的 StorageClient 库中。 :)
我刚刚写了一篇博文来回答你的问题: http : //blog.smarx.com/posts/testing-existence-of-a-windows-azure-blob 。
简短的回答是:使用 CloudBlob.FetchAttributes(),它对 blob 执行 HEAD 请求。
您需要捕获异常以测试 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;
}
}
}
如果 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 是微不足道的。
新的 Windows Azure 存储库已包含 Exist() 方法。 它位于 Microsoft.WindowsAzure.Storage.dll 中。
可用作 NuGet 包
创建者:微软
Id:WindowsAzure.Storage
版本:2.0.5.1
如果您不喜欢其他解决方案,这里有一个不同的解决方案:
我使用的是 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;
}
}
}
希望这对将来的人有所帮助。
如果您的 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
如果您不喜欢使用异常方法,那么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;
}
使用更新后的 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();
借助 Azure Blob 存储库 v12,可以使用BlobBaseClient.Exists()/BlobBaseClient.ExistsAsync()
回答了另一个类似的问题: https : //stackoverflow.com/a/63293998/4865541
Java 版本相同(使用新的 v12 SDK)
这使用共享密钥凭据授权,即帐户访问密钥。
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)
if ( container.exists() ) {
// perform operation when container exists
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.