Microsoft Azure上的Storage服务看起来非常牛逼,它是用来在云端存储数据和文件的服务,比如Azure里的虚拟机就是保存在Storage中的。当然我们可以用Storage做更多的事,比如有些数据并不适合存放在关系型数据库中,就像图片和附件,我们就可以使用Storage服务。

今天介绍的是Storage里的一种,Blob Storage。Windows Azure Storage还有其他两种存储:Table和Queue,但是我只开荒过Blob Storage,所以其他两个就只能以后介绍了。

使用Blob存储首先得建立一个Storage Account,Account中包含的是Container,这类似于文件夹,最后你的文件会存放在Container下,也就是Blob。

它们的关系就像这样(可耻的盗用了一张Azure官网的图片):

一、在Azure管理页面中建立Storage Account

1. 在Windows Azure管理页面中点击工具栏上的New按钮,如图,新建一个Storage Account。Geo-Replication可以不选,它是用来做异地备份的,但会要你掏额外的钱。

2. 创建好之后,我们可以直接在Azure管理页面里创建Container,当然,也可以通过编程方式来实现,不过不是这次介绍的范围。

ACCESS的意思是这个Container的访问权限,根据自己需要设置。创建完成之后就像这样:

URL是我们访问这个Container的地址,非常重要。

二、通过编程方式访问Blob Storage

首先要说明的是,你并不需要安装Azure SDK,也并不需要建立Cloud Service的项目。任何一个普通的.NET项目,比如Console Application,都可以通过安装NuGet包的方式得到Windows Azure的API。

这个例子里我用的就是Console Application。

1. 通过NuGet安装“Windows Azure Storage”,安装时候会把其他几个包自动带上,我们仅需要这些就可以了。

2. 配置Storage Account的连接字符串。

在App.config中加一个新的appSettings,名为diaospublicblob,稍候代码里会读这个连接字符串。

<appSettings>
    <add key="diaospublicblob" value="DefaultEndpointsProtocol=https;AccountName=eas01;AccountKey=×××××××××;BlobEndpoint=http://eas01.blob.core.windows.net/" />
</appSettings>

AccountKey可以在Azure管理界面上找到. 在你的Storage Account的页面下方的工具栏上,点击Manage Keys就有了。这里我们只需要Primary Access Key。

BlobEndPoint的地址同样在Azure的管理页面中可以找到:

3. 对Blob的任何操作都必须先获得Container的实例,代码如下:

// connect to azure storage
var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("diaospublicblob"));
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("diaostainer");

CloudConfigurationManager.GetSetting(string)的作用就是从刚才的App.config中读取Blob Storage的连接字符串。

必要的API都在这些命名空间里:

using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

 4. 向Container中上传本地文件:

private static void UploadFileToContainer(CloudBlobContainer container, string filePath, string uplodedFileName)
{
    var blockBlob = container.GetBlockBlobReference(uplodedFileName);
    using (var fileStream = System.IO.File.OpenRead(filePath))
    {
        blockBlob.UploadFromStream(fileStream);
    }
}
// upload file
UploadFileToContainer(container, @"E:\Fuck.txt", "Fuck.txt");

上传之后可以直接在Azure的管理界面里看到这个文件。也可以直接下载。

如果碰到重名的话,本地文件将会替换Azure上的文件。

5. 显示Container中的文件列表

private static void ListBlobsInContainer(CloudBlobContainer container)
{
    foreach (var item in container.ListBlobs(null, false))
    {
        if (item is CloudBlockBlob)
        {
            var blob = (CloudBlockBlob) item;

            Console.WriteLine("Block blob of length {0}: {1}", blob.Properties.Length, blob.Uri);
        }
        else if (item is CloudPageBlob)
        {
            var pageBlob = (CloudPageBlob) item;

            Console.WriteLine("Page blob of length {0}: {1}", pageBlob.Properties.Length, pageBlob.Uri);
        }
        else if (item is CloudBlobDirectory)
        {
            var directory = (CloudBlobDirectory) item;
            Console.WriteLine("Directory: {0}", directory.Uri);
        }
    }
}

结果如图

6. 下载文件到本地硬盘

private static void DownloadBlobFromContainer(CloudBlobContainer container, string blobName, string downloadFilePath)
{
    var blockBlob = container.GetBlockBlobReference(blobName);
    using (var fileStream = System.IO.File.OpenWrite(downloadFilePath))
    {
        blockBlob.DownloadToStream(fileStream);
    }
} 
// download file
DownloadBlobFromContainer(container, "Fuck.txt", @"E:\Fucked.txt");

7. 删除文件

private static void DeleteBlobFromContainer(CloudBlobContainer container, string blobName)
{
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
    blockBlob.Delete();
}
// delete file
DeleteBlobFromContainer(container, "Fuck.txt");