使用 F# 開始使用 Azure Blob 儲存體

Azure Blob 儲存體是可將非結構化的資料儲存在雲端作為物件/Blob 的服務。 Blob 儲存體可以儲存任何類型的文字或二進位資料,例如文件、媒體檔案或應用程式安裝程式。 Blob 儲存體也稱為物件儲存體。

本文示範如何使用 Blob 儲存體執行常見工作。 這些範例是使用適用於 .NET 的 Azure 儲存體用戶端程式庫,以 F# 所撰寫的。 涵蓋的工作包括如何上傳、列出、下載及刪除 Blob。

如需 Blob 儲存體的概念性概觀,請參閱 Blob 儲存體的 .NET 指南

必要條件

若要使用本指南,您必須先建立 Azure 儲存體帳戶。 您也需要擁有此帳戶的儲存體存取金鑰。

建立 F# 指令碼並啟動 F# 互動

本文中的範例可用於 F# 應用程式或 F# 指令碼。 若要建立 F# 指令碼,請在 F# 開發環境中建立副檔名為 .fsx 的檔案,例如 blobs.fsx

如何執行指令碼

F# 互動 dotnet fsi 可透過互動方式啟動,也可從命令列中啟動以執行指令碼。 命令列語法為

> dotnet fsi [options] [ script-file [arguments] ]

在指令碼中新增封裝

接下來,使用 #rnuget:package name 來安裝 Azure.Storage.Blobs 封裝和 open 命名空間。例如

> #r "nuget: Azure.Storage.Blobs"
open Azure.Storage.Blobs
open Azure.Storage.Blobs.Models
open Azure.Storage.Blobs.Specialized

新增命名空間宣告

blobs.fsx 檔案最上方加入下列 open 陳述式:

open System
open System.IO
open Azure.Storage.Blobs // Namespace for Blob storage types
open Azure.Storage.Blobs.Models
open Azure.Storage.Blobs.Specialized
open System.Text

取得您的連接字串

在本教學課程中,您需要 Azure 儲存體連接字串。 如需連接字串的詳細資訊,請參閱設定儲存體連接字串

在本教學課程中,您會在指令碼中輸入連接字串,如下所示:

let storageConnString = "..." // fill this in from your storage account

建立一些本機虛擬資料

開始之前,請在指令碼的目錄中建立一些虛擬本機資料。 稍後您會上傳此資料。

// Create a dummy file to upload
let localFile = "./myfile.txt"
File.WriteAllText(localFile, "some data")

建立 Blob 服務用戶端

BlobContainerClient 型別可讓您建立容器,並擷取儲存在 Blob 儲存體中的 Blob。 您可以使用下面這個辦法建立容器用戶端:

let container = BlobContainerClient(storageConnString, "myContainer")

現在,您可以開始撰寫程式碼,以讀取 Blob 儲存體的資料並將資料寫入其中。

建立容器

此範例說明如何建立尚不存在的容器:

container.CreateIfNotExists()

新的容器預設是私人容器,這表示您必須指定儲存體存取金鑰,才能從此容器下載 Blob。 如果您想要讓容器內的檔案可供所有人使用,您可以使用下列程式碼將容器設為公用:

let permissions = PublicAccessType.Blob
container.SetAccessPolicy(permissions)

網際網路上的任何人都可以看到公用容器中的 Blob,但只有在您擁有適當的帳戶存取金鑰或共用存取簽章時,才能修改或刪除 Blob。

上傳 Blob 至容器

Azure Blob 儲存體支援區塊 Blob 和分頁 Blob。 在大部分情況下,建議使用區塊 Blob 的類型。

若要將檔案上傳至區塊 Blob,請取得容器用戶端,並使用該參照來取得區塊 Blob 參照。 取得 Blob 參考後,即可藉由呼叫 Upload 方法,將任何資料流上傳至 Blob。 此作業會覆寫 Blob 的內容,如果沒有 Blob,則會建立新的區塊 Blob。

// Retrieve reference to a blob named "myblob.txt".
let blockBlob = container.GetBlobClient("myblob.txt")

// Create or overwrite the "myblob.txt" blob with contents from the local file.
use fileStream = new FileStream(localFile, FileMode.Open, FileAccess.Read, FileShare.Read)
do blockBlob.Upload(fileStream)

列出容器中的 Blob

若要列出容器中的 Blob,請先取得容器參考。 然後您即可使用容器的 GetBlobs 方法來擷取 Blob 和 (或) 其中的目錄。 若要針對傳回的 BlobItem 存取一組豐富的屬性與方法。

for item in container.GetBlobsByHierarchy() do
    printfn $"Blob name: {item.Blob.Name}"

例如,請考慮下列一組名為 photos 的容器中的區塊 Blob:

photo1.jpg
2015/architecture/description.txt
2015/architecture/photo3.jpg
2015/architecture/photo4.jpg
2016/architecture/photo5.jpg
2016/architecture/photo6.jpg
2016/architecture/description.txt
2016/photo7.jpg\

當您在容器上呼叫 GetBlobsByHierarchy (如上面範例所示) 時,系統會傳回階層式清單。

Directory: https://<accountname>.blob.core.windows.net/photos/2015/
Directory: https://<accountname>.blob.core.windows.net/photos/2016/
Block blob of length 505623: https://<accountname>.blob.core.windows.net/photos/photo1.jpg

下載 Blob

若要下載 Blob,請先擷取 Blob 參照,然後呼叫 DownloadTo 方法。 下列範例使用 DownloadTo 方法將 Blob 內容傳送給資料流物件,您接著可將該物件永久儲存成本機檔案。

// Retrieve reference to a blob named "myblob.txt".
let blobToDownload = container.GetBlobClient("myblob.txt")

// Save blob contents to a file.
do
    use fileStream = File.OpenWrite("path/download.txt")
    blobToDownload.DownloadTo(fileStream)

您也可以使用 DownloadContent 方法,將 Blob 的內容當成文字字串下載。

let text = blobToDownload.DownloadContent().Value.Content.ToString()

刪除 Blob

若要刪除 Blob,請先取得 Blob 參照,然後在該參考上呼叫 Delete 方法。

// Retrieve reference to a blob named "myblob.txt".
let blobToDelete = container.GetBlobClient("myblob.txt")

// Delete the blob.
blobToDelete.Delete()

以非同步方式列出分頁中的 Blob

如果您要列出大量 Blob,或想要控制您在單一列表作業中傳回的結果數,可以在結果頁面中列出 Blob。 此範例示範如何在頁面中傳回結果。

此範例會藉由使用 BlobClientGetBlobsByHierarchy 方法來示範階層式清單。

let ListBlobsSegmentedInHierarchicalListing(container:BlobContainerClient) =
        // List blobs to the console window, with paging.
        printfn "List blobs in pages:"

        // Call GetBlobsByHierarchy to return an async collection 
        // of blobs in this container. AsPages() method enumerate the values 
        //a Page<T> at a time. This may make multiple service requests.

        for page in container.GetBlobsByHierarchy().AsPages() do
            for blobHierarchyItem in page.Values do 
                printf $"The BlobItem is : {blobHierarchyItem.Blob.Name} "

        printfn ""

我們現在可以使用這個階層式清單常式,如下所示。 首先,上傳一些虛擬資料 (使用本教學課程稍早建立的本機檔案)。

for i in 1 .. 100 do
    let blob  = container.GetBlobClient($"myblob{i}.txt")
    use fileStream = System.IO.File.OpenRead(localFile)
    blob.Upload(localFile)

現在,呼叫常式。

ListBlobsSegmentedInHierarchicalListing container

寫入附加 Blob

附加 Blob 針對附加作業 (例如記錄) 最佳化。 如同區塊 Blob,附加 Blob 亦由區塊組成,但當您將新區塊加入附加 Blob 時,它一律會附加到 Blob 結尾。 您無法更新或刪除附加 Blob 中的現有區塊。 附加 Blob 的區塊識別碼不會公開,因為它們適用於區塊 Blob。

附加 Blob 中的每個區塊大小可能不同,最多 4 MB,而附加 Blob 最多可以包含 50,000 個區塊。 因此,附加 Blob 的大小上限略高於 195 GB (4 MB X 50,000 個區塊)。

下列範例中建立了新的附加 Blob,並附加一些資料,以模擬簡單的記錄作業。

// Get a reference to a container.
let appendContainer = BlobContainerClient(storageConnString, "my-append-blobs")

// Create the container if it does not already exist.
appendContainer.CreateIfNotExists() |> ignore

// Get a reference to an append blob.
let appendBlob = appendContainer.GetAppendBlobClient("append-blob.log")

// Create the append blob. Note that if the blob already exists, the 
// CreateOrReplace() method will overwrite it. You can check whether the 
// blob exists to avoid overwriting it by using CloudAppendBlob.Exists().
appendBlob.CreateIfNotExists()

let numBlocks = 10

// Generate an array of random bytes.
let rnd = Random()
let bytesArray = Array.zeroCreate<byte>(numBlocks)
rnd.NextBytes(bytesArray)

// Simulate a logging operation by writing text data and byte data to the 
// end of the append blob.
for i in 0 .. numBlocks - 1 do
    let msg = sprintf $"Timestamp: {DateTime.UtcNow} \tLog Entry: {bytesArray.[i]}\n"
    let array = Encoding.ASCII.GetBytes(msg);
    use stream = new MemoryStream(array)
    appendBlob.AppendBlock(stream)

// Read the append blob to the console window.
let downloadedText = appendBlob.DownloadContent().ToString()
printfn $"{downloadedText}"

如需三種 Blob 類型間差異的詳細資訊,請參閱了解區塊 Blob、分頁 Blob 和附加 Blob

並行存取

若要支援從多個用戶端或多個處理程序執行個體同時存取 Blob,您可以使用 ETag租用

  • Etag - 提供偵測 Blob 或容器已被另一個處理程序修改的方法

  • 租用 - 提供方法來取得在一段時間內對 Blob 的獨佔、可更新、寫入或刪除存取權

如需詳細資訊,請參閱在 Microsoft Azure 儲存體中管理並行

命名容器

Azure 儲存體中的每個 Blob 都必須位於容器中。 容器會形成 Blob 名稱的一部分。 例如,mydata 是這些範例 Blob URI 中容器的名稱:

  • https://storagesample.blob.core.windows.net/mydata/blob1.txt
  • https://storagesample.blob.core.windows.net/mydata/photos/myphoto.jpg

容器名稱必須是有效的 DNS 名稱,符合下列命名規則:

  1. 容器名稱必須以字母或數字開頭,而且只能包含字母、數字和虛線 (-) 字元。
  2. 每個虛線 (-) 字元的前後都必須是字母或數字;容器名稱中不允許連續虛線。
  3. 容器名稱中的所有字母都必須是小寫。
  4. 容器名稱長度必須介於 3 到 63 個字元之間。

容器的名稱一律必須小寫。 如果您在容器名稱中包含大寫字母,或違反容器命名規則,您可能會收到 400 錯誤 (不正確的要求)。

管理 Blob 的安全性

Azure 儲存體預設會限制擁有帳戶存取金鑰之帳戶擁有者的存取權來保護您的資料安全。 當您需要共用儲存體帳戶中的 Blob 資料時,請務必這麼做,才不會危害帳戶存取金鑰的安全性。 此外,您可以加密 Blob 資料,確保它在網路和 Azure 儲存體中是安全的。

控制 Blob 資料的存取

儲存體帳戶中的 Blob 資料預設只供儲存體帳戶擁有者存取。 向 Blob 儲存體驗證要求,預設需要帳戶存取金鑰。 不過,您可以讓特定的 blob 資料可供其他使用者使用。

加密 Blob 資料

Azure 儲存體支援在用戶端和伺服器上加密 blob 資料。

另請參閱