書籍転載
Windows Azure 実践クラウド・プログラミング
for C#/Visual Basic/PHP

クラウド環境の仮想的なNTFSファイルシステム「ドライブ」
― Chapter 4  Windows Azureストレージ - テーブル/キュー/ドライブ編 - ―

山田 祥寛
2010/09/29
Page1 Page2

[4]データアクセスコンポーネントを作成する

 ドライブ上でファイルの読み書きを行うためのデータアクセスコンポーネント(DriveDataクラス)を作成します。

using System;
using System.IO;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;

namespace CloudUI.Models
{
  public class DriveData
  {
    // ドライブオブジェクトを格納するプライベート変数
    private CloudDrive drive;

    // コンストラクタ(ドライブの初期化)
    public DriveData()
    {
      // アカウント情報の取得&ブロブクライアントの生成
      CloudStorageAccount account =
        CloudStorageAccount.FromConfigurationSetting(
          "MyStorage");
      var blob_cli = account.CreateCloudBlobClient();
      blob_cli.RetryPolicy = RetryPolicies.Retry(3,
        TimeSpan.FromMilliseconds(500));

      // ドライブオブジェクトの初期化
      var c = blob_cli.GetContainerReference("drives");
      var page = c.GetPageBlobReference("mydrive");
      LocalResource localCache =
        RoleEnvironment.GetLocalResource("MyCache");
      CloudDrive.InitializeCache(localCache.RootPath,
      localCache.MaximumSizeInMegabytes);
      drive = new CloudDrive(page.Uri, account.Credentials);
    }

    // メモ情報を登録(name:ファイル名、body:メモ本体)
    public void UpdateMemo(string name, string body)
    {
      // ドライブをマウント
      var letter = drive.Mount(10, DriveMountOptions.None);

      // パス文字列を生成
      var path = String.Format("{0}/{1}", letter, name);

      // 引数bodyをファイルに書き込み
      using (var writer = new StreamWriter(path))
      {
        writer.Write(body);
      }

      // ドライブをアンマウント
      drive.Unmount();
    }

    // 指定されたメモを取得
    public string GetMemoByName(string name)
    {
      // ドライブをマウント
      var letter = drive.Mount(10, DriveMountOptions.None);

      // パス文字列を生成
      var path = String.Format("{0}/{1}", letter, name);

      // 読み込み結果を格納するための変数
      var result = "";

      // ファイルが存在する場合には読み込み処理
      if (File.Exists(path))
      {
        using (var reader = new StreamReader(path))
        {
          result = reader.ReadToEnd();
        }
      }

      // ドライブをアンマウントの上、読み込み結果を返す
      drive.Unmount();
      return result;
    }
  }
}
Imports System.IO
Imports Microsoft.WindowsAzure.StorageClient
Imports Microsoft.WindowsAzure
Imports Microsoft.WindowsAzure.ServiceRuntime

Namespace Models
  Public Class DriveData
    ' ドライブ文字列、ドライブオブジェクトを格納する変数
    Private drive As CloudDrive

    ' コンストラクタ(ドライブの初期化)
    Public Sub New()
      ' アカウント情報の取得&ブロブクライアントの生成
      Dim account = _
        CloudStorageAccount.FromConfigurationSetting( _
          "MyStorage")
      Dim blob_cli = account.CreateCloudBlobClient()
      blob_cli.RetryPolicy = RetryPolicies.Retry(3, _
        TimeSpan.FromMilliseconds(500))

      ' ドライブオブジェクトの初期化
      Dim c = blob_cli.GetContainerReference("drives")
      Dim page = c.GetPageBlobReference("mydrive")
      Dim localCache = _
        RoleEnvironment.GetLocalResource("MyCache")
      CloudDrive.InitializeCache(localCache.RootPath, _
        localCache.MaximumSizeInMegabytes)
      drive = New CloudDrive(page.Uri, account.Credentials)
    End Sub

    ' メモ情報を登録(name:ファイル名、body:メモ本体)
    Public Sub UpdateMemo(ByVal name As String, ByVal body As String)

      ' ドライブをマウント
      Dim letter = drive.Mount(10, DriveMountOptions.None)

      ' パス文字列を生成
      Dim path = String.Format("{0}/{1}", letter, name)

      ' 引数bodyをファイルに書き込み
      Using writer = New StreamWriter(path)
        writer.Write(body)
      End Using

      ' ドライブをアンマウント
      drive.Unmount()
    End Sub

    ' 指定されたメモを取得
    Public Function GetMemoByName(ByVal name As String) As String
      ' ドライブをマウント
      Dim letter = drive.Mount(10, DriveMountOptions.None)

      ' パス文字列を生成
      Dim path = String.Format("{0}/{1}", letter, name)

      ' 読み込み結果を格納するための変数
      Dim result = ""

      ' ファイルが存在する場合には読み込み処理
      If File.Exists(path) Then
        Using reader = New StreamReader(path)
          result = reader.ReadToEnd()
        End Using
      End If

      // ドライブをアンマウントの上、読み込み結果を返す
      drive.Unmount()
      Return result
    End Function
  End Class
End Namespace
リスト4-23 ドライブ経由のファイルの読み書き(上:DriveData.cs、下:DriveData.vb)

 コンストラクタ、メモに書き込みを行うUpdateMemoメソッド、指定されたメモを読み込むGetMemoByNameメソッドと定義していますが、注目すべき点は実に太字の部分だけです。

 ドライブを利用するには、まずMountメソッドでドライブをマウントする必要があります。

string Mount(int size, DriveMountOptions opt)
構文  Mountメソッド
  size:キャッシュサイズ(メガバイト。0の場合はキャッシュを無効化)
  opt:マウントオプション(None|Force|FixFileSystemErrors)

 引数opt(マウントオプション)には、通常はNone(指定なし)を指定しておけば問題ありません。

 Mountメソッドは、マウントに成功すると、戻り値として割り当てられたドライブ文字列を返します。あとは、このドライブ文字列(変数letter)を利用することで、普通のファイルシステムにアクセスする要領で、ファイル操作を行うことができます。

 なお、ドライブはひとつのロールインスタンス(仮想マシン)に対してのみマウントを認めており、マウント時に排他的ロック(アクセスリース)の取得を試みます。マウントしたドライブはできる限り、早いタイミングでアンマウントするのが望ましいでしょう*53。アンマウントするのは、Unmountメソッドの役割です。

*53 他のロールインスタンスがロックを保持したままクラッシュしたようなケースでは、MountメソッドでForceオプションを指定することで、強制的にアクセスリースを解除し、マウントすることができます。

[5]ページをデザインする

 データアクセスコンポーネントが用意できたところで、最後にメモアプリケーションのユーザインターフェイスを用意します。

 以下は、新規に作成したMemo.aspxのフォームレイアウトと、サーバコントロールのプロパティ設定です。

図4-28:Memo.aspxのフォームレイアウト

 

コントロール プロパティ 設定値
DropDownList(ddlSubject) AutoPostBack True
Items 全般/執筆アイデア/技術/ネタ/日常
TextBox(txtMemo) Columns 50
Rows 15
TextMode MultiLine
Button(btnSave) Text 保存
表4-16 Memo.aspxのフォームレイアウト

 また、ソースビューからページロード時、選択ボックス変更時、ボタンクリック時の処理(イベントハンドラ)を追加します。

using System;
using System.Web.UI;
using CloudUI.Models;

namespace CloudUI.Chap4
{
  public partial class Memo : System.Web.UI.Page
  {
    private DriveData d;

    // ページロード時の処理
    protected void Page_Load(object sender, EventArgs e)
    {
      d = new DriveData();
      // 初期表示時にメモ情報を表示
      if (!Page.IsPostBack)
      {
        updateBody();
      }
    }

    // 選択ボックス変更時の処理
    protected void ddlSubject_SelectedIndexChanged(object sender, EventArgs e)
    {
      updateBody();
    }

    // [保存]ボタンクリック時の処理(メモの更新)
    protected void btnSave_Click(object sender, EventArgs e)
    {
      d.UpdateMemo(ddlSubject.SelectedValue, txtMemo.Text);
    }

    // 選択ボックスの選択に基づいて、メモ情報を表示
    private void updateBody()
    {
      txtMemo.Text = d.GetMemoByName(ddlSubject.SelectedValue);
    }
  }

}
Imports System
Imports System.Web.UI
Imports CloudUI.Models

Partial Public Class Memo
  Inherits System.Web.UI.Page

  Private d As DriveData

  ' ページロード時の処理
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    d = New DriveData()
    ' 初期表示時にメモ情報を表示
    If Not Page.IsPostBack Then
      updateBody()
    End If
  End Sub

  ' [保存]ボタンクリック時の処理(メモの更新)
  Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSave.Click
    d.UpdateMemo(ddlSubject.SelectedValue, txtMemo.Text)
  End Sub

  ' 選択ボックス変更時の処理
  Protected Sub ddlSubject_SelectedIndexChanged(ByVal sender As Object, ByVal e As System. BBEventArgs) Handles ddlSubject.SelectedIndexChanged
    updateBody()
  End Sub

  ' 選択ボックスの選択に基づいて、メモ情報を表示
  Private Sub updateBody()
    txtMemo.Text = d.GetMemoByName(ddlSubject.SelectedValue)
  End Sub

End Class
リスト4-24 メモ帳アプリケーションの動作(上:Memo.aspx.cs、下:Memo.aspx.vb)

 それぞれのイベントタイミングでは、データアクセスコンポーネントのメソッドを呼び出しているだけですので、殊更に特筆すべき点はありません。

 以上の手順を終えたら、サンプルを実行してみましょう。本節冒頭の図4-25のような結果が表示されること、メモ情報を更新できることなどを確認してください*54

*54 クラウド環境で動作する場合、ストレージサービスへの接続設定を[既定のHTTPSエンドポイントの使用]ではなく[既定のHTTPエンドポイントの使用]とする必要があります。さもないと、「ERROR_HTTPS_NOT_SUPPORTED」のようなエラーが発生しますので、注意してください。

【Note】ドライブの内容確認

 ドライブの内容は、開発ストレージUIから確認できます。

図4-29:開発ストレージUI

 メニューバーの[File]−[Open Azure Drive Folder in Windows Explorer]を選択すると、エクスプローラが開きますので、本項の例であれば「devstoreaccount1/images/memo」フォルダの配下を確認してください。

図4-30:ドライブの内容を確認

 同じく開発ストレージUIから[File]−[Reset Azure Drive]を選択することで、ドライブの内容をクリアすることもできます。開発ストレージの内容をクリアした場合には、必ずドライブもクリアするようにしてください*55。さもないと、本書サンプルでドライブの初期化に失敗する場合がありますので、要注意です。

*55 執筆時点のバージョンでは、ストレージと連動しては削除されないようです。

 次回は「Chapter 6 Azureアプリケーションの拡張と運用」の中から、「Azure AppFabricによるオンプレミス−クラウド連携」の部分を転載します。end of article

 

 INDEX
  [書籍転載]Windows Azure 実践クラウド・プログラミング for C#/Visual Basic/PHP
  クラウド環境の仮想的なNTFSファイルシステム「ドライブ」
    1.ドライブ利用の基本:ドライブの作成
  2.ドライブ利用の基本:ドライブの利用

インデックス・ページヘ 「Windows Azure 実践クラウド・プログラミング for C#/Visual Basic/PHP」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間