我们知道,由于云端的特殊性,通常情况下,对文件系统的读写建议使用Blob Storage来代替。这就产生了一个问题:对于一个已经写好的本地应用程序,其中使用了NTFS API对本地文件系统读写的代码是否需要进行完全重写以便迁移到Windows Azure平台上呢?答案是否定的。Windows Azure平台提供了Drive的功能。

在1.1版本的SDK中提供了CloudDrive类,能够将本地NTFS文件系统Mount到Blob Storage上。我们只要添加一小段代码来表明我们希望Mount Drive到Blob Storage上就能重用大部分已有的对本地文件系统访问的代码。这样,我们已有的程序能够无缝地迁移到Windows Azure上而不需要做大的改动。

在开始本教学之前,请确保你从Windows Azure 平台下载下载并安装了最新的Windows Azure开发工具。本教学使用Visual Studio 2010作为开发工具。

步骤一:创建解决方案和项目

由于我们要在本地模拟环境下测试Windows Azure Drive,首先,请确保Storage Emulator已经启动。我们可以找到管理器的进程手动启动或者让Visual Studio 2010帮助我们启动他。

右击工具栏中Windows Azure模拟器的图标,选择”Show Storage Emulator UI”。弹出如下图所示的窗口:

我们要关注的是Service management中Blob所在的一行。要确保Status为Running。

确认完毕后启动Visual Studio 2010,新建一个Cloud Service项目并为之添加一个Web Role。

步骤二:添加SDK程序集引用

请在项目属性页里确认项目的Target framework的值是.NET Framework 4或.NET Framework 3.5。然后在Web Role项目中添加对C:Program FilesWindows Azure SDKv1.3refMicrosoft.WindowsAzure.CloudDrive.dll的引用。该路径为SDK默认安装路径,如果你不能在这个路径中找到Microsoft.WindowsAzure.CloudDrive.dll请从SDK安装路径中寻找。

步骤三:添加代码

删除并重新创建Default.aspx 页面,然后在Default.aspx.cs中引用命名空间:

双击代码全选
1
2
3
4
5
using Microsoft.WindowsAzure;
 
using Microsoft.WindowsAzure.StorageClient;
 
using System.IO;

然后添加下列代码:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public partial class Default : System.Web.UI.Page
 
{
 
    string _driveLetter = WebRole.DriveLetter;
 
  
 
    protected void Page_Load(object sender, EventArgs e)
 
    {
 
        if (!IsPostBack)
 
        {
 
            Bind();
 
        }
 
    }
 
  
 
    void Bind()
 
    {
 
        // 显示被Mount的Drive根目录下的所有文件
 
        DirectoryInfo di = new DirectoryInfo(string.Format("{0}", _driveLetter));
 
        this.GridView1.DataSource = di.GetFiles();
 
        this.GridView1.DataBind();
 
    }
 
  
 
    protected void Button1_Click(object sender, EventArgs e)
 
    {
 
        // 在被Mount的Drive根目录下保存文件
 
        if (this.FileUpload1.HasFile)
 
        {
 
            File.WriteAllBytes(string.Format("{0}{1}", _driveLetter, this.FileUpload1.FileName), this.FileUpload1.FileBytes);
 
            Bind();
 
        }
 
    }
 
}

在Default.aspx中添加下列代码:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<form id="form1" runat="server">
 
  
 
    <asp:FileUpload ID="FileUpload1" runat="server" />
 
    <asp:Button ID="Button1" runat="server" Text="Upload" onclick="Button1_Click" />
 
  
 
    <asp:GridView AllowPaging="true" PageSize="20" ID="GridView1" runat="server">
 
    </asp:GridView>
 
  
 
</form>

接下来在WebRole.cs中引用命名空间:

双击代码全选
1
using Microsoft.WindowsAzure.StorageClient;

然后添加下列代码:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
public class WebRole : RoleEntryPoint
 
{
 
    public static string DriveLetter { get; private set; }
 
    CloudDrive myCloudDrive;
 
  
 
    public override bool OnStart()
 
    {
 
        // 当用配置文件中ConfigurationSettings时必须调用CloudStorageAccount.SetConfigurationSettingPublisher
 
        // 来说明当配置文件在发布后被更改时将采取何种操作
 
        CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
 
        {
 
               
 
            configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
 
  
 
            RoleEnvironment.Changed += (sender, arg) =>
 
            {
 
                if(arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
 
                    .Any((change) => (change.ConfigurationSettingName == configName)))
 
                {
 
  
 
                    if(!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
 
                    {
 
                        RoleEnvironment.RequestRecycle();
 
                    }
 
                }
 
            };
 
        });
 
  
 
        // For information on handling configuration changes
 
        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
 
  
 
        return base.OnStart();
 
    }
 
  
 
    public override void  Run()
 
    {
 
        CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
 
  
 
        LocalResource localCache = RoleEnvironment.GetLocalResource("InstanceDriveCache");
 
        CloudDrive.InitializeCache(localCache.RootPath, localCache.MaximumSizeInMegabytes);
 
  
 
        // 检查Container是否存在,不存在则创建
 
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
 
        blobClient.GetContainerReference("drives").CreateIfNotExist();
 
  
 
        // 创建Cloud Drive
 
        myCloudDrive = storageAccount.CreateCloudDrive(
 
            blobClient
 
            .GetContainerReference("drives")
 
            .GetPageBlobReference("mydrive.vhd")
 
            .Uri.ToString()
 
        );
 
  
 
        try
 
        {
 
            myCloudDrive.Create(64);
 
  
 
        }
 
        catch (CloudDriveException)
 
        {
 
  
 
        }
 
        DriveLetter = myCloudDrive.Mount(0, DriveMountOptions.Force);
 
  
 
        base.Run();
 
    }
 
  
 
    public override void OnStop()
 
    {
 
        myCloudDrive.Unmount();
 
  
 
        base.OnStop();
 
    }
 
}

最后,修改配置文件。在Cloud Service项目的ServiceConfiguration.cscfg中添加下列配置:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
 
<ServiceConfiguration serviceName="WindowsAzureDriveDemonstration"xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
 
  <Role name="WebRole1">
 
    <Instances count="1" />
 
    <ConfigurationSettings>
 
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
 
      <Setting name="DataConnectionString" value="UseDevelopmentStorage=true" />
 
    </ConfigurationSettings>
 
  </Role>
 
</ServiceConfiguration>

在ServiceDefinition.csdef中添加下列配置(注意将Sites部分的内容删除或注释掉):

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?xml version="1.0" encoding="utf-8"?>
 
<ServiceDefinition name="WindowsAzureDriveDemonstration" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
 
  <WebRole name="WebRole1">
 
    <Sites>
 
      <Site name="Web">
 
        <Bindings>
 
          <Binding name="Endpoint1" endpointName="Endpoint1" />
 
        </Bindings>
 
      </Site>
 
    </Sites>
 
    <Endpoints>
 
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
 
    </Endpoints>
 
    <Imports>
 
      <Import moduleName="Diagnostics" />
 
    </Imports>
 
    <LocalResources>
 
        <LocalStorage name="InstanceDriveCache" cleanOnRoleRecycle="false" sizeInMB="300" />
 
    </LocalResources>
 
    <ConfigurationSettings>
 
        <Setting name="DataConnectionString" />
 
    </ConfigurationSettings>
 
  </WebRole>
 
</ServiceDefinition>

步骤四:观察并分析代码

步骤三中的代码中,Default.aspx.cs的代码跟普通的ASP.NET项目代码没什么区别。我们把盘符抽离出来以便迁移到Windows Azure上。Default.aspx.cs中的代码跟Windows Azure唯一相关的一句语句就是string driveLetter = WebRole.DriveLetter。我们如果把WebRole.DriveLetter替换为本机盘符该ASP.NET程序将能够正常运行。

后面的代码示范了如何Mount Drive到Blob Storage。此外我们使用了本地缓存来缓存尚未被传递到Blob Storage的文件。

通过上面的例子可以看到,只需额外添加一小段代码,已有的使用NTFS API的程序能够很方便地迁移到Windows Azure平台上。

步骤五:运行程序

运行程序。上传几个文件。如果一切顺利你将看到下图所示的结果。可以看到文件的DirectoryName为“a:”。这就是被Mount到Blob Storage上的Drive的盘符。

需要注意的是,本例中我们并未修改WebRole的实例数,因此只有1个WebRole(发布到云端后将只有一个虚拟机被使用)。如果有两个实例,并且要让两个实例共享一个”网络硬盘“的话,本例中代码将不能正常工作。因为对于同一个Blob同时只能有一个虚拟机Mount。一个可能的解决方案是额外维护一个Web Service来管理Mount和UnMount Drive。进一步的讨论超出了本教学的范围。有兴趣的读者可以下载并参考Windows Azure Cloud Drive白皮书获取信息。

Windows Azure入门教学系列 (八):使用Windows Azure Drive的更多相关文章

  1. Windows Azure入门教学系列 (九):Windows Azure 诊断功能

    本文是Windows Azure入门教学的第九篇文章. 本文将会介绍如何使用Windows Azure 诊断功能.跟部署在本地服务器上的程序不同,当我们的程序发布到云端之后,我们不能使用通常的调试方法 ...

  2. Windows Azure入门教学系列 (一): 创建第一个WebRole程序

    原文 Windows Azure入门教学系列 (一): 创建第一个WebRole程序 在第一篇教学中,我们将学习如何在Visual Studio 2008 SP1中创建一个WebRole程序(C#语言 ...

  3. Windows Azure入门教学系列 (七):使用REST API访问Storage Service

    本文是Windows Azure入门教学的第七篇文章. 本文将会介绍如何使用REST API来直接访问Storage Service. 在前三篇教学中,我们已经学习了使用Windows Azure S ...

  4. Windows Azure中文博客 Windows Azure入门教学系列 (一): 创建第一个WebRole程序

    http://blogs.msdn.com/b/azchina/ 本文转自:http://blogs.msdn.com/b/azchina/archive/2010/02/09/windows-azu ...

  5. Windows Azure入门教学系列 (二):部署第一个Web Role程序

    本文是Windows Azure入门教学的第二篇文章. 在第一篇教学中,我们已经创建了第一个Web Role程序.在这篇教学中,我们将学习如何把该Web Role程序部署到云端. 注意:您需要购买Wi ...

  6. Windows Azure入门教学系列 (六):使用Table Storage

    本文是Windows Azure入门教学的第六篇文章. 本文将会介绍如何使用Table Storage.Table Storage提供给我们一个云端的表格结构.我们可以把他想象为XML文件或者是一个轻 ...

  7. Windows Azure入门教学系列 (五):使用Queue Storage

    本文是Windows Azure入门教学的第五篇文章. 本文将会介绍如何使用Queue Storage.Queue Storage提供给我们一个云端的队列.我们可以用Queue Storage来进行进 ...

  8. [转]Windows Azure入门教学系列 (六):使用Table Storage

    本文转自:http://blogs.msdn.com/b/azchina/archive/2010/03/11/windows-azure-table-storage.aspx 本文是Windows ...

  9. Windows Azure入门教学系列 (四):使用Blob Storage

    本文将会介绍如何使用Blob Storage.Blob Storage可以看做是云端的文件系统.与桌面操作系统上不同,我们是通过REST API来进行对文件的操作.有关REST API的详细信息,请参 ...

随机推荐

  1. ssh连接Linux自动断开后再也无法连上的问题

    近期公司测试机有点抓狂,情况是这样的:用SSH登录后正常使用,但另外一部电脑也在登录,这时候会发生全部断开的情况,再也无法连接,连IP都PING不通. 今天尝试在/etc/hosts.deny 加入如 ...

  2. Lua,Lua API,配置文件

    想像一个场景:你的c程序须要有一个窗体,你想让用户能够自己定义窗体大小.方法非常多.比方使用环境变量,或键值对的文件. 无论如何,你须要解析它. 使用lua配置文件是个不错的选择. 首先,你能够定义例 ...

  3. HDU 5091 线段树扫描线

    给出N个点.和一个w*h的矩形 给出N个点的坐标,求该矩形最多能够覆盖多少个点 对每一个点point(x.y)右边生成相应的点(x+w,y)值为-1: 纵向建立线段树,从左到右扫描线扫一遍.遇到点则用 ...

  4. word排版的一些小技巧积累

    先准备好样式 编辑前,可以先根据要求,设置好样式,可以免去编辑好后,再修改格式(这样要改好多文本的格式) docx doc的样式不能通用. .docx转.doc 从word2013自带的编辑公式,编辑 ...

  5. 一个简单的mfc单页界面文件读写程序(MFC 程序入口和执行流程)

    参考:MFC 程序入口和执行流程  http://www.cnblogs.com/liuweilinlin/archive/2012/08/16/2643272.html 程序MFCFlie      ...

  6. AOP 笔记

    http://blog.csdn.net/Intlgj/article/details/5671248 这篇文章里面介绍的非常好,值得阅读. 这里盗用里面的两张图片 [在没有AOP之前是这样的] [使 ...

  7. Chapter 9 原型模式

    原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 简单的说就是clone一个对象实例.使得clone出来的copy和原有的对象一模一样. 插一个简单使用clone的例子,如果 ...

  8. 关于libgdx中UI控件的旋转和缩放的备忘

    最近遇到这样一个问题,定义了一个ImageButton后,想对按钮进行下旋转,结果setRotation(-90f),不起作用.后来在官网上找到了原因 关于UI控件的旋转 缩放官网上有这样一段话(链接 ...

  9. iOS 本地化应用程序(NSLocalizedString)

    App本地化的需要不用讲大家也都明白,本文将介绍一种简单的方法来实现字符串的本地化. 在不考虑本地化的情况下,我们如果在代码中给一个Button定义title,一般会这样写: btn.titleLab ...

  10. 又见拦截导弹(LIS)

    又见拦截导弹 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 大家对拦截导弹那个题目应该比较熟悉了,我再叙述一下题意:某国为了防御敌国的导弹袭击,新研制出来一种导弹拦截系 ...