Azure 基礎:Blob Storage

sparkdev發表於2017-02-28

Azure Storage 是微軟 Azure 雲提供的雲端儲存解決方案,當前支援的儲存型別有 Blob、Queue、File 和 Table。

筆者在前文中介紹了 Table Storage 的基本用法,本文將通過 C# 程式碼介紹 Blob Storage 的主要使用方法。

Blob Storage 是什麼?

Azure Blob Storage 是用來存放大量的像文字、圖片、視訊等非結構化資料的儲存服務。我們可以在任何地方通過網際網路協議 http 或者 https 訪問 Blob Storage。說白了就是把檔案放在雲上,給它一個 URL,通過這個 URL 來訪問檔案。這就涉及到一個問題:如何控制訪問許可權?答案是我們可以根據自己的需要設定 Blob 物件是隻能被自己訪問,還是可以被所有人訪問。

下面是 Blog Storage 典型的應用場景:
1. 儲存圖片和文件,這些檔案可以直接通過瀏覽器訪問。
2. 支援分散式訪問,主要用於 cdn。
3. 提供視訊、音訊流。
4. 儲存基本的檔案備份和歸檔檔案。

Azure Blob Storage 的結構

下圖描述了 Blob Storage 的基本組織結構:

Azure Storage Account:
Storage Account 是用來管理 Azure Storage 的一個名稱空間,主要用來控制儲存資料的訪問許可權和計費。對 Blob、Queue、File 和 Table 這些 Azure 提供的儲存服務的訪問控制都是通過 Storage Account 來進行的,所以要想使用 Blob Storage,需要先建立你的 Storage Account。

Container
Container 中包含一組資源,所有的 Blob 都必須存在於 Container 中。一個 Storage Account 中可以包含無限個 Container,每個 Container 中也可以包含無限個 Blob。需要注意的是 Container 的名字必須全部小寫。

Blob
一個 Blob 就代表一個檔案。為了區分應用的場景及提升不同應用場景下儲存的效能,又為 Blob 劃分了不同的型別:block blobs, page blobs, append blobs。Block blobs 主要用來儲存靜態的檔案,比如圖片、電影和文件。Append blobs 與 block blobs 類似,但優化了 append 操作,主要的應用場景是儲存日誌檔案。Page blobs 則是針對頻繁的讀寫操作做了優化,像 Azure 上虛擬機器的磁碟都是使用的 page blobs。

如果您還不熟悉 Azure Storage Account 的使用,以及如何通過 WindowsAzure.Storage 庫訪問 Azure Storage,請參考前文《Azure 基礎:Table storage》中的介紹,這裡就不重複了。

為了方便檢視 C# 程式碼執行的結果,本文使用了 MS 釋出的一個 Azure Storage 客戶端工具:Microsoft Azure Storage Explorer,文中簡稱為 Storage Explorer。

接下來我們直接通過 C# 程式碼來介紹如何操作 Blob Storage。

建立 Blob Container

由於任何一個 Blob 都必須包含在一個 Blob Container 中,所以我們第一步先建立一個名為 "picturecontainer" 的 Blob Container:

// CloudStorageAccount 類表示一個 Azure Storage Account,我們需要先建立它的例項,才能訪問屬於它的資源。
// 注意連線字串中的 xxx 和 yyy,分別對應 Access keys 中的 Storage account name 和 key。
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=yyy");

// CloudBlobClient 類是 Windows Azure Blob Service 客戶端的邏輯表示,我們需要使用它來配置和執行對 Blob Storage 的操作。
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

// CloudBlobContainer 表示一個 Blob Container 物件。
CloudBlobContainer container = blobClient.GetContainerReference("picturecontainer");
// 如果不存在就建立名為 picturecontainer 的 Blob Container。
container.CreateIfNotExists();

執行上面的程式碼,然後開啟 Storage Explorer,重新整理一下,看到名為 "picturecontainer" 的 Blob Container 已經建立:

Container 名稱規則

MSDN 上不厭其煩的描述 Blob Container 的名稱規則,足以說明其重要性,本文試圖以簡要的文字進行描述:

1. 以小寫字母或數字開頭,只能包含字母、數字和 dash(-)。
2. 不能有連續的 dash(-),dash(-) 不能是第一個字元,也不能是最後一個字元。
3. 所有字元小寫,總長度為 3-63 字元。

違反任何一個規則,在建立 Blob Container 時都會受到 (400) Bad Request 錯誤。

上傳 Blob 檔案

我們上傳一個檔案到剛才建立的 Container 中:

// mypicture.png 為放在 container 中的 Blob 的名稱。
// GetBlockBlobReference 方法獲得一個 Block 型別的 Blob 物件的引用。
// 您可以根據應用的需要,分別呼叫 GetBlobReference,GetAppendBlobReference 或 GetPageBlobReference 來建立不同型別的 Blob 物件。
CloudBlockBlob blockBlob = container.GetBlockBlobReference("mypicture.png");
using (var fileStream = System.IO.File.OpenRead(file))
{
    // 這是一個同步執行的方法
    blockBlob.UploadFromStream(fileStream);
}

在程式碼中我們通過呼叫剛才建立的 Container 物件 container 的 GetBlockBlobReference 方法,獲得了一個 CloudBlockBlob 型別的物件。然後通過它的 UploadFromStream 方法把一個本地的檔案上傳到了雲端。
重新整理 Storage Explorer 看看上傳的結果:

圖片中顯示檔案已經上傳成功!

遍歷 Container 中的內容

如果我們想要羅列出一個 Container 中的所有 Blob 物件,就需要對整個 Container 進行遍歷操作:

foreach (IListBlobItem item in container.ListBlobs(null, false))
{
    if (item.GetType() == typeof(CloudBlockBlob))
    {
        CloudBlockBlob blob = (CloudBlockBlob)item;
        // todo something
    }
    else if (item.GetType() == typeof(CloudAppendBlob))
    {
        CloudAppendBlob appendBlob = (CloudAppendBlob)item;
        // todo something
    }
    else if (item.GetType() == typeof(CloudPageBlob))
    {
        CloudPageBlob pageBlob = (CloudPageBlob)item;
        // todo something
    }
    else if (item.GetType() == typeof(CloudBlobDirectory))
    {
        CloudBlobDirectory directory = (CloudBlobDirectory)item;
        // todo something
    }
}

這段程式碼中有兩處需要注意的地方:
1. 獲得的 Blob 物件是有型別的。
2. 可以獲得一個虛擬的目錄資訊,其實是對檔名稱的解析。比如一個 Blob 的名稱為 abc/flower.jpg,此時就能獲得一個名叫 abc 的虛擬目錄資訊。

下載 Blob 檔案

有上傳自然要有下載,看看下載一個 Blob 物件的程式碼:

// 建立名稱為 mypicture.png 的 Blob 物件的引用。
CloudBlockBlob blockBlob = container.GetBlockBlobReference("mypicture.png");
// 把檔案儲存到本地。
using (var fileStream = System.IO.File.OpenWrite(fileName))
{
    blockBlob.DownloadToStream(fileStream);
}

Mypicture.png 被下載到本地指定的檔案中。

設定 Blob 的訪問許可權

我們在本文開始的地方就強調可以通過 http 或 https 協議訪問 Blob Storage 檔案,現在我們就嘗試一下。
在 Storage Explorer 中選擇 mypicture.png,右鍵,選擇 "Copy URL to Clipboard"。把 URL 貼上到瀏覽器的位址列中。

怎麼回事?檔案不存在嗎?不是的,預設情況下,你的檔案是被保護的,只有通過你的 Storage Account 驗證後才能訪問。如果想要把它設定為任何人都能訪問,需要通過設定 Container 的許可權來實現。

private static void SetPublicContainerPermissions(CloudBlobContainer container)
{
    BlobContainerPermissions permissions = container.GetPermissions();
    // Container 中的所有 Blob 都能被訪問
    permissions.PublicAccess = BlobContainerPublicAccessType.Container;
    container.SetPermissions(permissions);
}

重新在瀏覽器中訪問一次試試:

可要小心喲,要是不小心把私密的檔案放到了這個 Container 中可就慘了!

刪除 Blob 檔案

mypicture.png 已經完成了演示的使命,可以刪除它了:

CloudBlockBlob blockBlob = container.GetBlockBlobReference("mypicture.png");
blockBlob.Delete();

總結

Blob Storage 以其豐富的型別(block, append, page)為各類應用場景提供了最優的選擇。本文僅僅是入門的介紹,更多的場景如用 Blob 儲存設定 cdn ,如何對資料進行加密儲存等內容都沒有涉及。希望對剛接觸 Azure 的朋友有所幫助。

相關文章