使用 .NET 上傳 Blob 物件

本文說明如何使用適用於 .NET 的 Azure 儲存體用戶端程式庫來上傳 Blob。 您可以從檔案路徑、資料流、二進位物件或文字字串,將資料上傳到區塊 Blob 物件。 您也可以開啟 Blob 串流並將資料寫入其中,或以區塊方式上傳大型 Blob。

必要條件

設定您的環境

如果沒有現有的專案,本章節會說明如何設定專案以使用適用於 .NET 的 Azure Blob 儲存體用戶端程式庫。 這些步驟包括封裝安裝、新增 using 指示詞,以及建立已授權的用戶端物件。 如需詳細資訊,請參閱 開始使用 Azure Blob 儲存體和 .NET。

安裝套件

從您的專案目錄中,使用 dotnet add package 命令安裝 Azure Blob 儲存體和 Azure 身分識別客戶端程式庫的套件。 需要 Azure.Identity 套件才能對 Azure 服務進行無密碼連線。

dotnet add package Azure.Storage.Blobs
dotnet add package Azure.Identity

新增 using 指示詞

將這些 using 指示詞新增至程式碼檔案頂端:

using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;

本文中的某些程式碼範例可能需要其他using指示詞。

建立用戶端物件

若要將應用程式連線至 Blob 儲存體,請建立 BlobServiceClient類別的執行個體。 下列範例示範如何使用 DefaultAzureCredential 來建立用戶端物件以進行授權:

public BlobServiceClient GetBlobServiceClient(string accountName)
{
    BlobServiceClient client = new(
        new Uri($"https://{accountName}.blob.core.windows.net"),
        new DefaultAzureCredential());

    return client;
}

您可以在 .NET 應用程式中註冊相依性插入的服務用戶端。

您也可以為特定容器或 Blob 建立客戶端物件。 若要深入了解建立和管理用戶端物件,請參閱 建立和管理與資料資源互動的用戶端物件。

授權

授權機制必須具有上傳 Blob 的必要權限。 若要使用 Microsoft Entra ID 進行授權(建議),您必須具備 Azure RBAC 內建角色 Storage Blob Data Contributor 或更高層級的角色。 若要深入了解,請參閱Put Blob (REST API)和Put Block (REST API)的授權指引。

將資料上傳至區塊 Blob

您可以使用下列任一方法,將資料上傳至區塊 Blob:

使用這些上傳方法時,用戶端程式庫可能會呼叫 Put Blob,或是一系列 Put Block 呼叫,後續再呼叫 Put Block List。 此行為取決於物件的整體大小,以及設定資料傳輸選項的方式。

若要在 Blob 儲存體開啟串流並寫入該串流,請使用下列其中一種方法:

注意

Azure 儲存體用戶端程式庫不支援並行寫入相同的 Blob。 如果您的應用程式需要多個處理程序寫入相同的 Blob,您應該實作並行控制策略,以提供可預測的體驗。 若要深入瞭解並行策略,請參閱 在 Blob 儲存體中管理並行。

從本機檔案路徑上傳區塊 Blob

下列範例會從本機檔案路徑上傳區塊 Blob:

public static async Task UploadFromFileAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    await blobClient.UploadAsync(localFilePath, true);
}

從串流上傳區塊 Blob

下列範例會透過先建立串流物件,再上傳該串流,來上傳區塊 Blob。

public static async Task UploadFromStreamAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, true);
    fileStream.Close();
}

從 BinaryData 物件上傳區塊 Blob

下列範例會從 BinaryData 物件上傳區塊 Blob。

public static async Task UploadFromBinaryDataAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    BinaryReader reader = new BinaryReader(fileStream);

    byte[] buffer = new byte[fileStream.Length];
    reader.Read(buffer, 0, buffer.Length);
    BinaryData binaryData = new BinaryData(buffer);

    await blobClient.UploadAsync(binaryData, true);

    fileStream.Close();
}

從字串上傳區塊 Blob

下列範例會從字串上傳區塊 Blob:

public static async Task UploadFromStringAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), overwrite: true);
}

上傳至 Blob 儲存體中的串流

您可以在 Blob 儲存體中開啟資料流,並將資料寫入其中。 下列範例會在 Blob 儲存體中建立 zip 檔案,並將檔案寫入其中。 不是在本機記憶體中建立 ZIP 檔案,而是一次只將一個檔案載入記憶體中。

警告

如果啟用物件複寫原則,此方法可能會非常昂貴,因為每次寫入串流都會建立新版本的 zip 檔案,而每個版本都會複製到目的地帳戶。 如果已啟用 Azure Blob 保存庫備份,則情況也是如此,因為保存庫備份會使用物件複寫。

public static async Task UploadToStreamAsync(
    BlobContainerClient containerClient,
    string localDirectoryPath)
{
    string zipFileName = Path.GetFileName(
        Path.GetDirectoryName(localDirectoryPath)) + ".zip";

    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(zipFileName);

    using (Stream stream = await blockBlobClient.OpenWriteAsync(true))
    {
        using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: false))
        {
            foreach (var fileName in Directory.EnumerateFiles(localDirectoryPath))
            {
                using (var fileStream = File.OpenRead(fileName))
                {
                    var entry = zip.CreateEntry(
                        Path.GetFileName(fileName), CompressionLevel.Optimal);
                    using (var innerFile = entry.Open())
                    {
                        await fileStream.CopyToAsync(innerFile);
                    }
                }
            }
        }
    }
}

使用組態選項上傳區塊 Blob

您可以在上傳 Blob 時定義用戶端程式庫設定選項。 這些選項也可進行調整,以改善效能、增強可靠性,並將成本最佳化。 下列程式碼範例示範如何在呼叫上傳方法時,使用 BlobUploadOptions 來定義設定選項。

指定上傳時的資料傳輸選項

您可以在 StorageTransferOptions 中設定值,以改善資料傳輸作業的效能。 下列程式碼範例示範如何設定 StorageTransferOptions 的值,並在 BlobUploadOptions 執行個體中包含選項。 此範例中提供的值並非旨在作為建議。 若要正確調整這些值,您必須考慮應用程式的特定需求。

public static async Task UploadWithTransferOptionsAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var transferOptions = new StorageTransferOptions
    {
        // Set the maximum number of parallel transfer workers
        MaximumConcurrency = 2,

        // Set the initial transfer length to 8 MiB
        InitialTransferSize = 8 * 1024 * 1024,

        // Set the maximum length of a transfer to 4 MiB
        MaximumTransferSize = 4 * 1024 * 1024
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferOptions = transferOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

若要深入了解微調資料傳輸選項,請參閱使用 .NET 進行上傳和下載的效能微調。

指定上傳時的傳輸驗證選項

使用 CRC64-NVME 的傳輸驗證可為 Azure Blob 儲存體 提供用戶端層級的資料完整性,讓您可以驗證應用程式傳送的資料與儲存在 Azure 中並從中讀取的資料相同。 啟用時,Blob SDK 會在上傳與下載操作中計算並驗證 CRC64-NVME 校驗和,而服務則獨立計算並驗證 CRC64-NVME 校驗碼,以取得與回傳資料。 每次請求及整個資料流都會進行驗證,確保即使資料以區塊上傳或範圍讀取等分割傳輸,整個 blob 也能被驗證。 更多細節請參見 結構性身體格式 。

透過 MD5 進行傳輸驗證,可驗證您的應用程式所傳送的資料是否與服務在每次請求中接收及回傳的資料相符。 啟用後,Blob SDK 會在上傳與下載操作中計算並驗證 MD5 雜湊值,而服務則獨立計算並驗證其所處理資料的 MD5 雜湊值。 驗證在 HTTP 請求與回應層級執行,有助於偵測每個傳輸資料區段的損壞,例如上傳時的個別區塊或讀取時的範圍。

您可以使用 BlobClientOptions 在用戶端層級定義傳輸驗證選項,其會將驗證選項套用至從 BlobClient 執行個體呼叫的所有方法。 或者,你也可以在方法層級使用 BlobUploadOptions 覆蓋傳輸驗證選項。 下列程式碼範例示範如何建立 BlobUploadOptions 物件,並指定用於產生總和檢查碼的演算法。

public static async Task UploadWithChecksumAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var validationOptions = new UploadTransferValidationOptions
    {
        ChecksumAlgorithm = StorageChecksumAlgorithm.Auto
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferValidation = validationOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

下表顯示總和檢查碼演算法的可用選項,如 StorageChecksumAlgorithm 所定義:

名稱 值 描述
自動 0 建議。 允許程式庫選擇演算法。 不同的程式庫版本可能會選擇不同的演算法。 在 用戶端函式庫 版本 12.28.0+ 中自動選擇 StorageCrc64
無 1 未選取演算法。 請勿計算或要求校驗和。
MD5 2 標準 MD5 雜湊演算法。
StorageCrc64 3 Azure 儲存體自訂 CRC64-NVME。

注意

如果要求中指定的總和檢查碼不符合服務計算的總和檢查碼,上傳作業就會失敗。 使用預設重試原則時,不會重試作業。 在 .NET 中,會擲回 RequestFailedException,並帶有狀態碼 400 和錯誤碼 Md5Mismatch 或 Crc64Mismatch,取決於使用的​​演算法。

使用索引標記上傳

Blob 索引標記會使用鍵/值標記屬性來分類儲存體帳戶中的資料。 這些標記會自動編製索引,並公開為可搜尋的多維度索引,以便輕鬆地尋找資料。 您可以將標籤新增至 BlobUploadOptions 執行個體,並將該執行個體傳遞至 UploadAsync 方法。

以下範例會上傳帶有索引標籤的區塊 Blob:

public static async Task UploadBlobWithTagsAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    BlobUploadOptions options = new BlobUploadOptions();
    options.Tags = new Dictionary<string, string>
    {
        { "Sealed", "false" },
        { "Content", "image" },
        { "Date", "2020-04-20" }
    };

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), options);
}

設定 Blob 上傳時的存取層級

您可以使用 BlobUploadOptions 類別在 Blob 上傳時設定存取層。 下列程式碼範例顯示如何在上傳 Blob 時設定存取層:

public static async Task UploadWithAccessTierAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(fileName);

    var uploadOptions = new BlobUploadOptions()
    {
        AccessTier = AccessTier.Cool
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blockBlobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

僅可對區塊 Blob 設定存取層。 您可以將區塊 Blob 的存取層設定為 Hot、Cool、Cold 或 Archive。 若要將存取層設定為 Cold,您必須最少使用用戶端程式庫版本 12.15.0。

若要深入了解存取層,請參閱存取層概觀。

透過暫存區塊和提交來上傳區塊 Blob

您可以手動暫存個別資料區塊,以進一步控制如何將上傳項目分割成區塊。 當構成 Blob 的所有區塊都已暫存後,您便可以將其提交到 Blob 儲存體。 您可以使用此方法,藉由平行上傳區塊來增強效能。

public static async Task UploadBlocksAsync(
    BlobContainerClient blobContainerClient,
    string localFilePath,
    int blockSize)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blobClient = blobContainerClient.GetBlockBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    ArrayList blockIDArrayList = new ArrayList();
    byte[] buffer;

    var bytesLeft = (fileStream.Length - fileStream.Position);

    while (bytesLeft > 0)
    {
        if (bytesLeft >= blockSize)
        {
            buffer = new byte[blockSize];
            await fileStream.ReadAsync(buffer, 0, blockSize);
        }
        else
        {
            buffer = new byte[bytesLeft];
            await fileStream.ReadAsync(buffer, 0, Convert.ToInt32(bytesLeft));
            bytesLeft = (fileStream.Length - fileStream.Position);
        }

        using (var stream = new MemoryStream(buffer))
        {
            string blockID = Convert.ToBase64String(
                Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));

            blockIDArrayList.Add(blockID);
            await blobClient.StageBlockAsync(blockID, stream);
        }
        bytesLeft = (fileStream.Length - fileStream.Position);
    }

    string[] blockIDArray = (string[])blockIDArrayList.ToArray(typeof(string));

    await blobClient.CommitBlockListAsync(blockIDArray);
}

資源

若要深入了解如何使用適用於 .NET 的 Azure Blob 儲存體用戶端程式庫來上傳 Blob,請參閱下列資源。

程式碼範例

REST API 操作

適用於 .NET 的 Azure SDK 包含建置在 Azure REST API 之上的程式庫,可讓您透過熟悉的 .NET 範例與 REST API 作業進行互動。 用來上傳 BLOb 的用戶端程式庫方法會使用下列 REST API 作業:

另請參閱

  • 本文是適用於 .NET 的 Blob 儲存體開發人員指南的一部分。 若要深入了解,請參閱位於建置 .NET 應用程式的開發人員指南文章完整清單。