2010年07月28日
川俣晶の縁側ソフトウェア技術雑記 total 7178 count

Azureのストレージのブロブにデータがあるかを調べる方法

Written By: 川俣 晶連絡先

 良く分からなかったので、試行錯誤したメモ。

目的 §

 ブロブに既にデータをアップロード済みか、まだ無いのかを調べたい。

参考情報 §

 Blobs – Azure Storage Client v1.0 - Windows Liveに以下のようにあります。

There is no method to detect container existence and if this is required the pattern is to call FetchAttributes() and detect the error if it doesn’t exist.

(超意訳:コンテナの存在をチェックするメソッドは無いけど、もしそれが要求された場合は、FetchAttributesメソッドを呼んでエラーを検出すると無いことが分かる)

 知りたいのはコンテナではなくブロブのアイテムですが、まあFetchAttributesメソッドを呼んで確実に不在のケースだけ検出してみましょう。

サンプルソース (ただし全てではない。これだけでは動かない) §

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using Microsoft.WindowsAzure;

using Microsoft.WindowsAzure.ServiceRuntime;

using Microsoft.WindowsAzure.StorageClient;

namespace WebRole1

{

    public partial class _Default : System.Web.UI.Page

    {

        public static CloudStorageAccount CSA   // get CloudStorageAccount

        {

            get;

            set;

        }

        private static CloudBlobClient cloudBlobClient = null;

        public static CloudBlobClient CBC  // get CloudBlobClient

        {

            get

            {

                if (cloudBlobClient != null) return cloudBlobClient;

                cloudBlobClient = CSA.CreateCloudBlobClient();

                return cloudBlobClient;

            }

        }

        protected void Page_Load(object sender, EventArgs e)

        {

            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>

            {

                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                RoleEnvironment.Changed += (mysender, arg) =>

                {

                    if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()

                        .Any((change) => (change.ConfigurationSettingName == configName)))

                    {

                        if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))

                        {

                            RoleEnvironment.RequestRecycle();

                        }

                    }

                };

            });

            CSA = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");

            CloudBlobContainer cont = CBC.GetContainerReference("testcontainer001");

            cont.CreateIfNotExist();

            // 正常ケースのテスト。アップロードしたアイテムはあるはず

            CloudBlob blob1 = cont.GetBlobReference("test001");

            blob1.UploadText("Hello!\r\n");

            string result1 = blob1.DownloadText();

            // 見つからないケース

            string result2;

            try

            {

                CloudBlob blob2 = cont.GetBlobReference("test002");

                blob2.FetchAttributes();

                result2 = "Succeded!\r\n";

            }

            catch (StorageClientException ex)

            {

                //if( ex.ErrorCode == StorageErrorCode.BlobNotFound ) //←これではダメ

                if (ex.ErrorCode == StorageErrorCode.ResourceNotFound) //←これなら動いた

                {

                    result2 = "not found\r\n";  // 見つからないケース

                }

                else

                {

                    result2 = ex.ToString() + "\r\n";   // その他のエラーになったケース

                }

            }

            Label1.Text = string.Format("{0} {1}", result1, result2);

        }

    }

}

実行結果 §

Hello! not found

感想 §

 これでいいのかなあ。例外捕まえないと分からないのかなあ。

2010年7月29日追記 §

  • //if( ex.ErrorCode == StorageErrorCode.BlobNotFound ) //←これではダメ
  • if (ex.ErrorCode == StorageErrorCode.ResourceNotFound) //←これなら動いた

 と書いたばかりなのに、別のソースでBlobNotFoundの方で返ってくるケースに遭遇。両方ともあり得るのかな?