C# 正在检查Azure存储中是否存在blob
我有一个非常简单的问题(我希望如此!)-我只想知道某个特定容器中是否存在一个blob(具有我定义的名称)。如果它确实存在,我将下载它,如果它不存在,我将做其他事情C# 正在检查Azure存储中是否存在blob,c#,azure,azure-blob-storage,C#,Azure,Azure Blob Storage,我有一个非常简单的问题(我希望如此!)-我只想知道某个特定容器中是否存在一个blob(具有我定义的名称)。如果它确实存在,我将下载它,如果它不存在,我将做其他事情 我在Intertube上做了一些搜索,很明显以前有一个函数叫做DoesExist或类似的东西。。。但是,与许多Azure API一样,它似乎不再存在(或者如果存在,它有一个非常巧妙的伪装名称)。注意:这个答案现在已经过时了。请参阅Richard的答案,以获取检查是否存在的简单方法 不,你没有错过一些简单的东西。。。我们在新的Stora
我在Intertube上做了一些搜索,很明显以前有一个函数叫做DoesExist或类似的东西。。。但是,与许多Azure API一样,它似乎不再存在(或者如果存在,它有一个非常巧妙的伪装名称)。注意:这个答案现在已经过时了。请参阅Richard的答案,以获取检查是否存在的简单方法 不,你没有错过一些简单的东西。。。我们在新的StorageClient库中很好地隐藏了此方法。:) 我刚刚写了一篇博客来回答你的问题:
简短的回答是:使用CloudBlob.FetchAttributes(),它对blob执行HEAD请求。如果blob是公共的,当然,您只需发送一个HTTP HEAD请求——从知道如何执行该请求的无数语言/环境/平台中发送——并检查响应 核心Azure API是基于RESTful XML的HTTP接口。StorageClient库是许多可能的包装器之一。下面是Sriram Krishnan在Python中所做的另一件事: 它还显示了如何在HTTP级别进行身份验证
我在C#中为自己做了类似的事情,因为我更喜欢从HTTP/REST的角度看Azure,而不是从StorageClient库的角度看Azure。很长一段时间以来,我甚至没有费心实现ExistsBlob方法。我所有的blob都是公共的,做HTTP头很简单。需要捕获一个异常来测试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;
}
}
}
如果您不喜欢使用异常方法,那么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;
}
新的Windows Azure存储库已包含Exist()方法。 它位于Microsoft.WindowsAzure.Storage.dll中 可作为NuGet软件包提供
创建人:Microsoft
Id:WindowsAzure.Storage
版本:2.0.5.1
新API具有.Exists()函数调用。只需确保使用
getblockblobreeference
,它不会执行对服务器的调用。它使功能变得简单,如下所示:
public static bool BlobExistsOnCloud(CloudBlobClient client,
string containerName, string key)
{
return client.GetContainerReference(containerName)
.GetBlockBlobReference(key)
.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()
如果您的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
如果您不喜欢其他解决方案,这里有一个不同的解决方案: 我正在使用Azure.Storage.Blobs NuGet包的12.4.1版。 我得到一个Azure.Pageable对象,它是容器中所有blob的列表。然后,我检查BlobItem的名称是否等于容器中使用LINQ的每个blob的name属性。(当然,如果一切都有效)
使用Azure.Storage.Blobs;
使用Azure.Storage.Blobs.Models;
使用System.Linq;
使用System.Text.RegularExpressions;
公共级AzureBlobStorage
{
私有BlobServiceClient(BlobServiceClient);
公共AzureBlobStorage(字符串连接字符串)
{
this.ConnectionString=ConnectionString;
_blobServiceClient=新的blobServiceClient(this.ConnectionString);
}
公共bool IsContainerNameValid(字符串名称)
{
返回Regex.IsMatch(名称,“^[a-z0-9](?!.*)[a-z0-9-]{1,61}[a-z0-9]$”,RegexOptions.Singleline | RegexOptions.CultureInvariant);
}
public bool ContainerExists(字符串名称)
{
返回(IsContainerNameValid(名称)?\u blobServiceClient.GetBlobContainerClient(名称).Exists():false);
}
公共Azure.Pageable GetBlob(字符串containerName,字符串前缀=null)
{
尝试
{
返回(ContainerExists)(containerName)?
_blobServiceClient.GetBlobContainerClient(containerName).GetBlob(BlobTraits.All,BlobStates.All,前缀,默认值(System.Threading.CancellationToken))
:空);
}
抓住
{
投掷;
}
}
public bool BlobExists(字符串containerName、字符串blobName)
{
尝试
{
返回(从GetBlobs(containerName)中的b返回)
其中b.Name==blobName
选择b).FirstOrDefault()!=null;
}
抓住
{
投掷;
}
}
}
希望这对将来的人有所帮助。对于Azure Blob存储库v12,您可以使用
BlobBaseClient.Exists()/BlobBaseClient.ExistsAsync()
回答了另一个类似的问题:同样的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
}
谢谢大家。由于我正在使用StorageClient(并且更愿意让我所有的Azure存储访问都通过该库),我使用了smarx建议的FetchAttributes和CheckforExceptions方法。它确实“感觉”有点不舒服,因为我不喜欢将异常作为我业务逻辑的正常部分抛出-但希望这可以在未来的StorageClient版本中得到修复:)FetchAttributes()需要很长时间才能运行(至少在开发存储中),如果文件尚未完全提交,也就是说,只是由未提交的块组成。如果您要像OP计划的那样获取blob,
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;
}
}
}
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
}