Windows Azure ストレージ Blobをいじってみた
Page Blob、Block Blobの二種類が存在するBlobについてちょっとコードをまとめがてらに書いてみる。AzureTrainingKitからコードをぱくってますので、ホントに動かすコードはそちらから参照してください。
Blob コンテナの作成
Blobコンテナの作成を行っています。Blobコンテナに対するアクセス権も設定しています。
//ConnectionStringの設定 var account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); //BlobClientの作成 var client = account.CreateCloudBlobClient(); //コンテナの参照を取得 var container = client.GetContainerReference("myContainer"); container.CreateIfNotExist(); //コンテナのアクセスをPublicに設定 var permissions = container.GetPermissions(); permissions.PublicAccess = BlobContainerPublicAccessType.Container; container.SetPermissions(permissions);
Blobの保存
適当にBlobにデータを保存する処理を記述しました。メタデータをアタッチする処理に注意してください。
string contentType = "image/jpeg" string blobname = "image_" + Guid.NewGuid().ToString(); //Blobの参照取得 var blob = this.GetContainer().GetBlobReference(blobname); //コンテントタイプの設定 blob.Properties.ContentType = contentType; //Blobに8KBまで付加できるメタデータの設定 var metadata = new NameValueCollection(); metadata["hogehoge"] = "something metadata"; //Blobにメタデータを追加 blob.Metadata.Add(metadata); //Blobにバイトデータを格納 blob.UploadByteArray(data);
Blobの参照
Blobのメタデータを参照する場合、実はちょっとテクニックが必要です。
//Blob検索オプション?のインスタンスを生成 var blobRequestOptions = new BlobRequestOptions(){ UseFlatBlobListing = true, BlobListingDetails = BlobListingDetails.All }; //Blobの検索オプションを指定してリストを取得 this.GetContainer().ListBlobs(blobRequestOptions);
例では「BlobRequestOptions」のインスタンスを生成して、「BlobListingDetails」プロパティに"ALL"を指定してBlobのリストを生成しています。引数なしの「ListBlobs()」メソッドを実行した場合、Blobのメタデータ取得ができないという事実があったり。
Blobのその他注意点
Blobからデータを取得し、PageBlobやらBlockBlobに変換して処理を行っています。以下のコード例は「ホントにコンパイル通しただけ」の白物ですので、どうやってPageBlobとBlockBlobを取得したらよいかの参考程度に留めてください。
var blob = this.GetContainer().ListBlobs(new BlobRequestOptions() { UseFlatBlobListing = true, BlobListingDetails = BlobListingDetails.All }).OfType<CloudBlob>().FirstOrDefault(); try { var pageBlob = blob.ToPageBlob; var length = blob.OpenRead().Length; //var blockSize = blob.OpenRead().BlockSize; なぜか例外が…orz //PageBlobにしかないメソッド //このメソッドでランダムアクセス可能? pageBlob.WritePages(new MemoryStream(), length); } catch (Exception ex) { Console.Write(ex); } try { var blockBlob = blob.ToBlockBlob; var length = blockBlob.OpenRead().Length; //var blocksize = blockBlob.OpenRead().BlockSize; なぜか例外が…orz blockBlob.PutBlock("blockId", new MemoryStream(), "contentMD5");//BlockBlobにしかないメソッド } catch (Exception ex) { Console.Write(ex); }
以下が主な疑問点
- Blob保存時にPageやらBlockやらを決めるのでなく、Blob参照のタイミングでBlobの形式を決めるのか?
- Page Blobが1TBまで、Block Blobが200Gまでの格納サイズ上限だったはずだけど、どこでBlobのタイプを分けて制御してるんだろう?
- CloudPageBlobに対して、GetPageRanges()メソッドを実行したら"The blob type is invalid for this operation"と例外を吐かれた
- CloudBlockBlob.OpenRead().BlockSize、CloudPageBlob.OpenRead().BlockSizeの値が取得できない