Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正在检查Azure存储中是否存在blob_C#_Azure_Azure Blob Storage - Fatal编程技术网

C# 正在检查Azure存储中是否存在blob

C# 正在检查Azure存储中是否存在blob,c#,azure,azure-blob-storage,C#,Azure,Azure Blob Storage,我有一个非常简单的问题(我希望如此!)-我只想知道某个特定容器中是否存在一个blob(具有我定义的名称)。如果它确实存在,我将下载它,如果它不存在,我将做其他事情 我在Intertube上做了一些搜索,很明显以前有一个函数叫做DoesExist或类似的东西。。。但是,与许多Azure API一样,它似乎不再存在(或者如果存在,它有一个非常巧妙的伪装名称)。注意:这个答案现在已经过时了。请参阅Richard的答案,以获取检查是否存在的简单方法 不,你没有错过一些简单的东西。。。我们在新的Stora

我有一个非常简单的问题(我希望如此!)-我只想知道某个特定容器中是否存在一个blob(具有我定义的名称)。如果它确实存在,我将下载它,如果它不存在,我将做其他事情


我在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 
    }