আজুর স্টোরেজে কোনও ব্লব রয়েছে কিনা তা পরীক্ষা করা হচ্ছে


131

আমি একটি খুব সাধারণ প্রশ্ন পেয়েছি (আমি আশা করি!) - আমি কেবল একটি নির্দিষ্ট ধারকটিতে একটি ব্লব (আমার সংজ্ঞায়িত একটি নাম সহ) বিদ্যমান কিনা তা জানতে চাই। এটি উপস্থিত থাকলে আমি এটি ডাউনলোড করব এবং যদি এটি না থাকে তবে আমি অন্য কিছু করব।

আমি ইন্টারটিউবগুলিতে কিছু অনুসন্ধান করেছি এবং স্পষ্টতই সেখানে ডোনএক্সিস্ট নামে একটি ফাংশন ব্যবহার করা হত বা এর অনুরূপ কিছু ... তবে অ্যাজুর এপিআইয়ের অনেকের মতো এটি আর নেই বলে মনে হয় (বা যদি এটি হয় তবে একটি রয়েছে) খুব চালাকভাবে ছদ্মবেশী নাম)।


ধন্যবাদ সবাইকে. যেহেতু আমি স্টোরেজক্লিয়েন্ট ব্যবহার করছি (এবং আমার সমস্ত অ্যাজুর স্টোরেজ অ্যাক্সেসটি সেই লাইব্রেরির মধ্য দিয়ে যেতে পছন্দ করবে) আমি স্মারেক্স প্রস্তাবিত ফেচ অ্যাট্রিবিউটস-এবং-চেক-ফর-ব্যতিক্রম পদ্ধতির সাথে গিয়েছিলাম। এটি কিছুটা 'অনুভব' করে না, এতে আমার ব্যবসায়িক যুক্তির সাধারণ অংশ হিসাবে ব্যতিক্রম হওয়া পছন্দ হয় না - তবে আশা করি এটি ভবিষ্যতের স্টোরেজ ক্লিনেন্ট সংস্করণে ঠিক করা যেতে পারে :)
জন

উত্তর:


202

নতুন এপিআই-তে .Exists () ফাংশন কল রয়েছে। কেবলমাত্র নিশ্চিত হয়ে নিন যে আপনি এটি ব্যবহার করেছেন GetBlockBlobReferenceযা সার্ভারে কল সম্পাদন করে না। এটি ফাংশনটিকে তত সহজ করে তোলে:

public static bool BlobExistsOnCloud(CloudBlobClient client, 
    string containerName, string key)
{
     return client.GetContainerReference(containerName)
                  .GetBlockBlobReference(key)
                  .Exists();  
}

6
আছে .. একটি অজগর সংস্করণ?
আনপ্যাটেল

2
ভাবছেন যে ব্লব পরীক্ষা করার জন্য আপনি কী চার্জ পাবেন? এই ডিফোটি ব্লবটি ডাউনলোড করার চেষ্টা করার চেয়ে আরও ভাল যাওয়ার উপায় বলে মনে হচ্ছে।
ডার্মফ্রঞ্চ

10
@ এনপ্যাটেল, অজগর সংস্করণ:len(blob_service.list_blobs(container_name, file_name)) > 0
রাএসআই

3
আপনি নিজের উত্তরটি আপডেট করতে পারেন যা দিয়ে নুগেট প্যাকেজ ইনস্টল করা উচিত
ব্যাটম্যাকি

9
দ্রষ্টব্য: মাইক্রোসফ্ট হিসাবে। উইন্ডোজআজুরি। স্টোরেজ সংস্করণ 8.1.4.0 (। নেট ফ্রেমওয়ার্ক v4.6.2) ExistsAsync () এর পক্ষে বিদ্যমান () পদ্ধতিটি বিদ্যমান নেই যা নেট নেট কোর প্রকল্পগুলির জন্য ইনস্টল করবে এমন সংস্করণ
অ্যাডাম হার্ডি

49

দ্রষ্টব্য: এই উত্তরটি এখন পুরানো। অস্তিত্বের জন্য যাচাই করার সহজ পদ্ধতির জন্য দয়া করে রিচার্ডের উত্তরটি দেখুন

না, আপনি সাধারণ কিছু মিস করছেন না ... আমরা নতুন স্টোরেজ ক্লায়েন্ট লাইব্রেরিতে এই পদ্ধতিটি লুকানোর জন্য ভাল কাজ করেছি। :)

আপনার প্রশ্নের উত্তর দেওয়ার জন্য আমি কেবল একটি ব্লগ পোস্ট লিখেছি: http://blog.smarx.com/posts/testing-existance-of-a-windows-azure-blob

সংক্ষিপ্ত উত্তরটি হ'ল ক্লাউডব্লব.ফ্যাচএট্রিবিউটস () ব্যবহার করুন যা ব্লবের বিরুদ্ধে একটি হেড অনুরোধ করে।


1
ফ্যাচএট্রিবিউটস () ফাইলটি পুরোপুরি প্রতিশ্রুতিবদ্ধ না হয়ে থাকলে, চালানোর জন্য (কমপক্ষে বিকাশের স্টোরেজে) দীর্ঘ সময় নেয়, অর্থাত কেবল অবিরাম ব্লক সমন্বিত।
টম রবিনসন

7
যদি আপনি ওপি যেমন করতে চান তেমনভাবে ব্লবটি আনতে চলেছেন তবে কেন এখনই কন্টেন্টটি ডাউনলোড করে ডাউনলোড করবেন না? এটি যদি না থাকে তবে এটি ঠিক ফেচআ্যাট্রিবিউটের মতো ছুঁড়ে ফেলবে। প্রথমে এই চেকটি করাটি কেবল একটি অতিরিক্ত অনুরোধ, বা আমি কি কিছু হারিয়ে ফেলছি?
মার্নিক্স ভ্যান ভ্যালেন

মার্নিক্স একটি চমৎকার পয়েন্ট তোলে। আপনি যদি যাইহোক এটি ডাউনলোড করতে চলেছেন তবে কেবল এটি ডাউনলোড করার চেষ্টা করুন।
ব্যবহারকারী 94559

@ মার্নিক্স: আপনি যদি এমন কিছু কল করেন তবে OpenReadএটি কোনও খালি স্ট্রিম বা এ জাতীয় কিছু ফেলে দেবে না বা ফেরত দেবে না। আপনি এটি থেকে ডাউনলোড শুরু করলেই ত্রুটিগুলি পাবেন। এটা সব এক জায়গায় এই হ্যান্ডেল করতে অনেক সহজ :)
porges

1
@ পেজেস: ক্লাউড অ্যাপ্লিকেশন ডিজাইনিং করা "ব্যর্থতার জন্য নকশা" সম্পর্কে প্রায় সমস্ত কিছুই। এই পরিস্থিতিটি কীভাবে সঠিকভাবে পরিচালনা করতে হয় তা নিয়ে প্রচুর আলোচনা রয়েছে। তবে সাধারণভাবে - আমি কেবল গিয়ে এটি ডাউনলোড করব, তারপরে নিখোঁজ ব্লব ত্রুটিগুলি পরিচালনা করব। শুধু তা-ই নয়, তবে আমি যদি প্রতিটি ব্লব এক্সটেনশনের জন্য যাচ্ছি তবে আমি স্টোরেজ লেনদেনের সংখ্যা বাড়িয়ে দিচ্ছি, এইভাবে আমার বিল। ব্যতিক্রম / ত্রুটিগুলি পরিচালনা করার জন্য আপনার কাছে এখনও একটি জায়গা থাকতে পারে।
আস্তায়কভ

16

মনে হচ্ছে খোঁড়াটি যে এটি পরীক্ষা করার জন্য আপনাকে একটি ব্যতিক্রম ধরা দরকার to

public static bool Exists(this CloudBlob blob)
{
    try
    {
        blob.FetchAttributes();
        return true;
    }
    catch (StorageClientException e)
    {
        if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
        {
            return false;
        }
        else
        {
            throw;
        }
    }
}

9

যদি ব্লবটি সর্বজনীন হয় তবে অবশ্যই, আপনি কেবল একটি এইচটিটিপি হেড অনুরোধ পাঠাতে পারেন - জিলিয়ন ভাষাগুলি / পরিবেশ / প্ল্যাটফর্মগুলির মধ্যে যেগুলি কীভাবে তা জানে - এবং প্রতিক্রিয়াটি পরীক্ষা করতে পারে।

মূল অ্যাজুর এপিআইগুলি হ'ল রেস্টলফুল এক্সএমএল-ভিত্তিক HTTP ইন্টারফেস। স্টোরেজক্লিয়েন্ট লাইব্রেরি তাদের চারপাশের অনেকগুলি সম্ভাব্য মোড়কের মধ্যে একটি। পাইথনে শ্রীরাম কৃষ্ণন আরও একটি কাজ এখানে করেছেন:

http://www.sriramkrishnan.com/blog/2008/11/python-wrapper-for-windows-azure.html

এটি HTTP স্তরে কীভাবে প্রমাণীকরণ করতে হয় তাও দেখায়।

আমি সি # তে নিজের জন্যও একই কাজ করেছি, কারণ আমি স্টোরেজক্লিয়েন্ট লাইব্রেরির লেন্সের চেয়ে এইচটিটিপি / আরএসটি-র লেন্সের মাধ্যমে আজুর দেখতে পছন্দ করি। বেশ কিছু সময়ের জন্য আমি একটি অ্যাসিস্টব্লব পদ্ধতিটি প্রয়োগ করার জন্যও মাথা ঘামাইনি। আমার সমস্ত ব্লবগুলি সর্বজনীন ছিল এবং এইচটিটিপি হেড করা তুচ্ছ ছিল।


5

নতুন উইন্ডোজ অ্যাজুরি স্টোরেজ লাইব্রেরিতে ইতিমধ্যে বিদ্যমান () পদ্ধতি রয়েছে। এটি মাইক্রোসফ্টে রয়েছে। উইন্ডোজআজুরি.স্টোরেজ.ডিল।


মাইক্রোসফ্ট
আইডি: উইন্ডোজএজুরি.স্টোরেজ
সংস্করণ: ২.০.৫.১ নুগেট প্যাকেজ হিসাবে উপলভ্য

এমএসডিএনও দেখুন


2

আপনি যদি ব্যতিক্রম পদ্ধতিটি ব্যবহার করতে পছন্দ করেন না তবে জুডেল যা পরামর্শ দেয় তার মূল সি # সংস্করণ নীচে রয়েছে is আপনার অন্য সম্ভাব্য প্রতিক্রিয়াগুলিও হ্যান্ডেল করা উচিত যদিও সচেতন হন।

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Method = "HEAD";
HttpWebResponse myResp = (HttpWebResponse)myReq.GetResponse();
if (myResp.StatusCode == HttpStatusCode.OK)
{
    return true;
}
else
{
    return false;
}

4
HttpWebRequest.GetResponse 404 আছে সেখানে ব্যতিক্রম ছুঁড়ে ফেলেছে So তাই আমি দেখতে পাচ্ছি না যে আপনার কোডটি কীভাবে ব্যতিক্রমগুলি পরিচালনা করার প্রয়োজনটিকে নষ্ট করবে?
নিতরাম্ক

ন্যায্য বিন্দু. আমার কাছে আবর্জনা মনে হচ্ছে যে getResponse () সেই সময়ে ছুড়ে ফেলেছে! আমি প্রত্যাশা করব এটি 404 ফিরিয়ে দেবে কারণ এটিই প্রতিক্রিয়া !!!
ম্যাড পিয়েরে

2

যদি আপনার ব্লবটি সর্বজনীন হয় এবং আপনার কেবল মেটাডেটা দরকার:

        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

1

আপডেট হওয়া এসডিকে দিয়ে একবার আপনার কাছে ক্লাউডব্লব রেফারেন্স থাকলে আপনি আপনার রেফারেন্সে অস্তিত্বগুলি () কল করতে পারেন।

Http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.blob.cloud blockblob.exists.aspx দেখুন


1

এইভাবেই আমি এটি করি। যাদের এটি প্রয়োজন তাদের জন্য পূর্ণ কোড দেখাচ্ছে।

        // 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.
        }

1

যদিও এখানে বেশিরভাগ উত্তর প্রযুক্তিগতভাবে সঠিক, বেশিরভাগ কোডের নমুনাগুলি সিঙ্ক্রোনাস / ব্লকিং কল করছে। আপনি যদি কোনও খুব পুরানো প্ল্যাটফর্ম বা কোড বেসের দ্বারা আবদ্ধ না হন, এইচটিটিপি কলগুলি সর্বদা অযৌক্তিকভাবে করা উচিত এবং এসডিকে এ ক্ষেত্রে সম্পূর্ণ সমর্থন করে। শুধু ExistsAsync()পরিবর্তে ব্যবহার করুন Exists()

bool exists = await client.GetContainerReference(containerName)
    .GetBlockBlobReference(key)
    .ExistsAsync();

আপনি সঠিক, পুরাতন .এক্সজিস্ট () সেরা বিকল্প নয়। যাইহোক, যখন পুরাতন এপিআই সমলয় করা হয়, ব্যবহার অপেক্ষায় রয়েছেন ExistsAsync ঘটায় এছাড়াও সমলয় যাবে। সুতরাং, আমি সম্মত হব যে এইচটিটিপি কলগুলি সাধারণত অ্যাসিনক্রোনাস হওয়া উচিত । তবে এই কোডটি এমন নয়। তবুও, নতুন এপিআইয়ের জন্য +1!
রিচার্ড

2
ধন্যবাদ, তবে আমি এর চেয়ে বেশি একমত হতে পারি না। Exists()এটি সমকালীন যে এটি শেষ না হওয়া পর্যন্ত এটি একটি থ্রেড অবরোধ করে। await ExistsAscyn()এটি অ্যাসিঙ্ক্রোনাস যে এটি না। উভয় একই লজিক্যাল প্রবাহকে অনুসরণ করে যে পূর্বের কোডটি শেষ না হওয়া পর্যন্ত কোডের পরবর্তী লাইনটি শুরু হয় না, তবে এটি এর অবরুদ্ধ প্রকৃতি এটি অবিচ্ছিন্ন ExistsAsyncকরে তোলে।
টড মেনিয়ার


1

আপনি যদি অন্য সমাধানগুলি পছন্দ না করেন তবে এখানে একটি আলাদা সমাধান রয়েছে:

আমি Azure.Soage.Blobs নিউগেট প্যাকেজটির 12.4.1 সংস্করণটি ব্যবহার করছি।

আমি একটি Azure.Pageable অবজেক্ট পাই যা একটি ধারকগুলিতে সমস্ত ব্লবগুলির একটি তালিকা। আমি তখন পরীক্ষা যদি নাম BlobItem সাথে অন্যান্যকে সমতুল্য স্থির নাম ধারক ব্যবহার ভিতরে প্রতিটি ফোঁটা সম্পত্তির LINQ । (অবশ্যই যদি সবকিছু বৈধ হয় তবে অবশ্যই)

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;
        }
    }
}

আশা করি এটি ভবিষ্যতে কাউকে সহায়তা করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.