使用 .NET 開發 Azure 檔案服務

了解開發使用 Azure 檔案儲存體來儲存資料的 .NET 應用程式基本概念。 本文說明如何建立簡單的主控台應用程式,以使用 .NET 和 Azure 檔案儲存體來執行下列作業:

  • 取得檔案的內容。
  • 設定檔案共用的大小上限或配額。
  • 建立檔案的共用存取簽章 (SAS)。
  • 將檔案複製到相同儲存體帳戶中的另一個檔案。
  • 將檔案複製到相同儲存體帳戶中的 Blob。
  • 建立檔案共用的快照集。
  • 從共用快照集還原檔案。
  • 使用 Azure 儲存體計量進行疑難排解。

若要深入了解 Azure 檔案儲存體,請參閱什麼是 Azure 檔案儲存體?

提示

請查看 Azure 儲存體程式碼範例儲存機制

如需可供您下載和執行的簡易端對端 Azure 儲存體程式碼範例,請查看我們的 Azure 儲存體範例清單。

適用於

檔案共用類型 SMB NFS
標準檔案共用 (GPv2)、LRS/ZRS Yes No
標準檔案共用 (GPv2)、GRS/GZRS Yes No
進階檔案共用 (FileStorage)、LRS/ZRS Yes No

了解 .NET API

Azure 檔案服務會提供兩種廣泛的方法給用戶端應用程式:伺服器訊息區 (SMB) 和 REST。 在 .NET 中,System.IOAzure.Storage.Files.Shares API 會將這些方法抽象化。

API 使用時機 備註
System.IO 您的應用程式:
  • 需要使用 SMB 讀取/寫入檔案
  • 正在可透過連接埠 445 存取您 Azure 檔案服務帳戶的裝置上執行
  • 不需要管理檔案共用的任何系統管理設定
使用 Azure 檔案儲存體透過 SMB 實作的檔案 I/O,通常是與使用任何網路檔案共用或本機儲存裝置的 I/O 相同。 如需 .NET 中許多功能的簡介,包括檔案 I/O,請參閱主控台應用程式教學課程。
Azure.Storage.Files.Shares 您的應用程式:
  • 因為防火牆或 ISP 條件約束,所以無法在連接埠 445 上使用 SMB 存取 Azure 檔案儲存體
  • 需要系統管理功能,例如設定檔案共用的配額,或建立共用存取簽章的能力
本文示範使用 REST (而不是 SMB) 的檔案 I/O Azure.Storage.Files.Shares 用法和管理檔案共用。

建立主控台應用程式並取得組件

您可以在任何類型的 .NET 應用程式中使用 Azure 檔案儲存體用戶端程式庫。 這些應用程式包括 Azure 雲端、Web、桌面和行動應用程式。 在本指南中,為求簡化,我們會建立主控台應用程式。

在 Visual Studio 中,建立新的 Windows 主控台應用程式。 下列步驟說明如何在 Visual Studio 2019 中建立主控台應用程式。 這些步驟類似其他 Visual Studio 版本中的步驟。

  1. 啟動 Visual Studio 並選取 [建立新專案]
  2. 在 [建立新專案] 中,針對 C# 選擇 [主控台應用程式 (.NET Framework)],然後選取 [下一步]
  3. 在 [設定新專案] 中,輸入應用程式的名稱並選取 [建立]

將本文中的所有程式碼範例新增至 Program.cs 檔案中的 Program 類別。

使用 NuGet 來安裝必要的封裝

請在您的專案中參考這些套件:

您可以使用 NuGet 來取得套件。 執行下列步驟:

  1. 在 [方案總管] 中,以滑鼠右鍵按一下您的專案並選擇 [管理 NuGet 套件]

  2. 在 [NuGet 套件管理員] 中,選取 [瀏覽]。 然後搜尋並選擇 Azure.Core,然後選取 [安裝]

    此步驟會安裝套件及其相依性。

  3. 搜尋並安裝這些封裝:

    • Azure.Storage.Blobs
    • Azure.Storage.Files.Shares
    • System.Configuration.ConfigurationManager

將您的儲存體帳戶認證儲存到 App.config 檔案

接著,將您的認證儲存到專案的 App.config 檔案。 在 [方案總管] 中,按兩下 App.config 並編輯檔案,使其類似於下列範例。

請使用您的儲存體帳戶名稱來取代 myaccount,並使用您的儲存體帳戶金鑰來取代 mykey

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="StorageConnectionString" 
      value="DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;EndpointSuffix=core.windows.net" />
    <add key="StorageAccountName" value="myaccount" />
    <add key="StorageAccountKey" value="mykey" />
  </appSettings>
</configuration>

注意

Azurite 儲存體模擬器目前不支援 Azure 檔案儲存體。 您的連接字串必須以雲端中的 Azure 儲存體帳戶為目標,才能與 Azure 檔案儲存體搭配使用。

新增 using 指示詞

在 [方案總管] 中,開啟 Program.cs 檔案,並且使用指示詞將下列項目新增至檔案頂端。

using System;
using System.Configuration;
using System.IO;
using System.Threading.Tasks;
using Azure;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Files.Shares;
using Azure.Storage.Files.Shares.Models;
using Azure.Storage.Sas;

以程式設計方式存取檔案共用

Program.cs 檔案中,新增下列程式碼,以程式設計方式存取檔案共用。

下列方法會建立檔案共用,如果檔案共用尚未存在。 該方法會藉由從連接字串建立 ShareClient 物件開始。 然後,此範例會嘗試下載我們稍早建立的檔案。 從 Main() 呼叫這個方法。

//-------------------------------------------------
// Create a file share
//-------------------------------------------------
public async Task CreateShareAsync(string shareName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a ShareClient which will be used to create and manipulate the file share
    ShareClient share = new ShareClient(connectionString, shareName);

    // Create the share if it doesn't already exist
    await share.CreateIfNotExistsAsync();

    // Ensure that the share exists
    if (await share.ExistsAsync())
    {
        Console.WriteLine($"Share created: {share.Name}");

        // Get a reference to the sample directory
        ShareDirectoryClient directory = share.GetDirectoryClient("CustomLogs");

        // Create the directory if it doesn't already exist
        await directory.CreateIfNotExistsAsync();

        // Ensure that the directory exists
        if (await directory.ExistsAsync())
        {
            // Get a reference to a file object
            ShareFileClient file = directory.GetFileClient("Log1.txt");

            // Ensure that the file exists
            if (await file.ExistsAsync())
            {
                Console.WriteLine($"File exists: {file.Name}");

                // Download the file
                ShareFileDownloadInfo download = await file.DownloadAsync();

                // Save the data to a local file, overwrite if the file already exists
                using (FileStream stream = File.OpenWrite(@"downloadedLog1.txt"))
                {
                    await download.Content.CopyToAsync(stream);
                    await stream.FlushAsync();
                    stream.Close();

                    // Display where the file was saved
                    Console.WriteLine($"File downloaded: {stream.Name}");
                }
            }
        }
    }
    else
    {
        Console.WriteLine($"CreateShareAsync failed");
    }
}

設定檔案共用的大小上限

從 Azure 檔案儲存體用戶端程式庫 5.x 版開始,您可以設定檔案共用配額 (或大小上限)。 您也可以檢查有多少資料目前儲存在共用上。

設定共用的配額會限制儲存在共用上的檔案大小總計。 如果共用上的檔案大小總計超過配額,用戶端就無法增加現有檔案的大小。 用戶端也無法建立新檔案,除非這些檔案是空的。

下列範例示範如何檢查共用的目前使用狀況,以及如何設定共用的配額。

//-------------------------------------------------
// Set the maximum size of a share
//-------------------------------------------------
public async Task SetMaxShareSizeAsync(string shareName, int increaseSizeInGiB)
{
    const long ONE_GIBIBYTE = 10737420000; // Number of bytes in 1 gibibyte

    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a ShareClient which will be used to access the file share
    ShareClient share = new ShareClient(connectionString, shareName);

    // Create the share if it doesn't already exist
    await share.CreateIfNotExistsAsync();

    // Ensure that the share exists
    if (await share.ExistsAsync())
    {
        // Get and display current share quota
        ShareProperties properties = await share.GetPropertiesAsync();
        Console.WriteLine($"Current share quota: {properties.QuotaInGB} GiB");

        // Get and display current usage stats for the share
        ShareStatistics stats = await share.GetStatisticsAsync();
        Console.WriteLine($"Current share usage: {stats.ShareUsageInBytes} bytes");

        // Convert current usage from bytes into GiB
        int currentGiB = (int)(stats.ShareUsageInBytes / ONE_GIBIBYTE);

        // This line sets the quota to be the current 
        // usage of the share plus the increase amount
        await share.SetQuotaAsync(currentGiB + increaseSizeInGiB);

        // Get the new quota and display it
        properties = await share.GetPropertiesAsync();
        Console.WriteLine($"New share quota: {properties.QuotaInGB} GiB");
    }
}

產生檔案或檔案共用的共用存取簽章

從 Azure 檔案儲存體用戶端程式庫 5.x 版開始,您可以產生檔案共用或個別檔案的共用存取簽章 (SAS)。

下列範例方法會傳回指定共用中檔案的 SAS。

//-------------------------------------------------
// Create a SAS URI for a file
//-------------------------------------------------
public Uri GetFileSasUri(string shareName, string filePath, DateTime expiration, ShareFileSasPermissions permissions)
{
    // Get the account details from app settings
    string accountName = ConfigurationManager.AppSettings["StorageAccountName"];
    string accountKey = ConfigurationManager.AppSettings["StorageAccountKey"];

    ShareSasBuilder fileSAS = new ShareSasBuilder()
    {
        ShareName = shareName,
        FilePath = filePath,

        // Specify an Azure file resource
        Resource = "f",

        // Expires in 24 hours
        ExpiresOn = expiration
    };

    // Set the permissions for the SAS
    fileSAS.SetPermissions(permissions);

    // Create a SharedKeyCredential that we can use to sign the SAS token
    StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey);

    // Build a SAS URI
    UriBuilder fileSasUri = new UriBuilder($"https://{accountName}.file.core.windows.net/{fileSAS.ShareName}/{fileSAS.FilePath}");
    fileSasUri.Query = fileSAS.ToSasQueryParameters(credential).ToString();

    // Return the URI
    return fileSasUri.Uri;
}

如需建立和使用共用存取簽章的詳細資訊,請參閱共用存取簽章的運作方式

複製檔案

從 Azure 檔案儲存體用戶端程式庫 5.x 版開始,您可以將檔案複製到另一個檔案、將檔案複製到 Blob 或將 Blob 複製到檔案。

您也可以使用 AzCopy 將檔案複製到另一個檔案,或將 Blob 複製到檔案或反向操作。 請參閱開始使用 AzCopy

注意

如果要將 Blob 複製到檔案,或將檔案複製到 Blob,您必須使用共用存取簽章 (SAS) 來授權來源物件的存取全,即使是在相同的儲存體帳戶內進行複製也一樣。

將檔案複製到另一個檔案

下列範例會將檔案複製到相同共用中的另一個檔案。 您可以使用共用金鑰驗證來執行複製作業,因為這項作業會複製相同儲存體帳戶內的檔案。

//-------------------------------------------------
// Copy file within a directory
//-------------------------------------------------
public async Task CopyFileAsync(string shareName, string sourceFilePath, string destFilePath)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Get a reference to the file we created previously
    ShareFileClient sourceFile = new ShareFileClient(connectionString, shareName, sourceFilePath);

    // Ensure that the source file exists
    if (await sourceFile.ExistsAsync())
    {
        // Get a reference to the destination file
        ShareFileClient destFile = new ShareFileClient(connectionString, shareName, destFilePath);

        // Start the copy operation
        await destFile.StartCopyAsync(sourceFile.Uri);

        if (await destFile.ExistsAsync())
        {
            Console.WriteLine($"{sourceFile.Uri} copied to {destFile.Uri}");
        }
    }
}

將檔案複製到 Blob

下列範例會建立檔案,並將其複製到相同儲存體帳戶內的 Blob。 此範例會建立來源檔案的 SAS,供服務用來在複製作業期間授權來源檔案存取權。

//-------------------------------------------------
// Copy a file from a share to a blob
//-------------------------------------------------
public async Task CopyFileToBlobAsync(string shareName, string sourceFilePath, string containerName, string blobName)
{
    // Get a file SAS from the method created ealier
    Uri fileSasUri = GetFileSasUri(shareName, sourceFilePath, DateTime.UtcNow.AddHours(24), ShareFileSasPermissions.Read);

    // Get a reference to the file we created previously
    ShareFileClient sourceFile = new ShareFileClient(fileSasUri);

    // Ensure that the source file exists
    if (await sourceFile.ExistsAsync())
    {
        // Get the connection string from app settings
        string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

        // Get a reference to the destination container
        BlobContainerClient container = new BlobContainerClient(connectionString, containerName);

        // Create the container if it doesn't already exist
        await container.CreateIfNotExistsAsync();

        BlobClient destBlob = container.GetBlobClient(blobName);

        await destBlob.StartCopyFromUriAsync(sourceFile.Uri);

        if (await destBlob.ExistsAsync())
        {
            Console.WriteLine($"File {sourceFile.Name} copied to blob {destBlob.Name}");
        }
    }
}

您可以用相同方式將 Blob 複製到檔案。 如果來源物件為 Blob,則請建立 SAS,以便在複製作業期間授權該 Blob 存取權。

共用快照集

從 Azure 檔案儲存體用戶端程式庫的 8.5 版開始,您可以建立共用快照集。 您也可以列出或瀏覽共用快照集,並將共用快照集刪除。 一旦建立,共用快照集就會是唯讀的。

建立共用快照集

下列範例會建立檔案共用快照集。

//-------------------------------------------------
// Create a share snapshot
//-------------------------------------------------
public async Task CreateShareSnapshotAsync(string shareName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareServiceClient = new ShareServiceClient(connectionString);

    // Instantiate a ShareClient which will be used to access the file share
    ShareClient share = shareServiceClient.GetShareClient(shareName);

    // Ensure that the share exists
    if (await share.ExistsAsync())
    {
        // Create a snapshot
        ShareSnapshotInfo snapshotInfo = await share.CreateSnapshotAsync();
        Console.WriteLine($"Snapshot created: {snapshotInfo.Snapshot}");
    }
}

列出共用快照集

下列範例會列出共用上的快照集。

//-------------------------------------------------
// List the snapshots on a share
//-------------------------------------------------
public void ListShareSnapshots()
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareServiceClient = new ShareServiceClient(connectionString);

    // Display each share and the snapshots on each share
    foreach (ShareItem item in shareServiceClient.GetShares(ShareTraits.All, ShareStates.Snapshots))
    {
        if (null != item.Snapshot)
        {
            Console.WriteLine($"Share: {item.Name}\tSnapshot: {item.Snapshot}");
        }
    }
}

列出共用快照集內的檔案和目錄

下列範例會瀏覽共用快照集內的檔案和目錄。

//-------------------------------------------------
// List the snapshots on a share
//-------------------------------------------------
public void ListSnapshotContents(string shareName, string snapshotTime)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Get a ShareClient
    ShareClient share = shareService.GetShareClient(shareName);

    Console.WriteLine($"Share: {share.Name}");

    // Get as ShareClient that points to a snapshot
    ShareClient snapshot = share.WithSnapshot(snapshotTime);

    // Get the root directory in the snapshot share
    ShareDirectoryClient rootDir = snapshot.GetRootDirectoryClient();

    // Recursively list the directory tree
    ListDirTree(rootDir);
}

//-------------------------------------------------
// Recursively list a directory tree
//-------------------------------------------------
public void ListDirTree(ShareDirectoryClient dir)
{
    // List the files and directories in the snapshot
    foreach (ShareFileItem item in dir.GetFilesAndDirectories())
    {
        if (item.IsDirectory)
        {
            Console.WriteLine($"Directory: {item.Name}");
            ShareDirectoryClient subDir = dir.GetSubdirectoryClient(item.Name);
            ListDirTree(subDir);
        }
        else
        {
            Console.WriteLine($"File: {dir.Name}\\{item.Name}");
        }
    }
}

從共用快照集還原檔案共用或檔案

擷取檔案共用的快照集可讓您將個別檔案或整個檔案共用復原。

您可以從檔案共用快照集還原檔案,方法是查詢檔案共用的共用快照集。 然後,您可以擷取屬於特定共用快照集的檔案。 您可以使用該版本直接讀取或還原檔案。

//-------------------------------------------------
// Restore file from snapshot
//-------------------------------------------------
public async Task RestoreFileFromSnapshot(string shareName, string directoryName, string fileName, string snapshotTime)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Get a ShareClient
    ShareClient share = shareService.GetShareClient(shareName);

    // Get as ShareClient that points to a snapshot
    ShareClient snapshot = share.WithSnapshot(snapshotTime);

    // Get a ShareDirectoryClient, then a ShareFileClient to the snapshot file
    ShareDirectoryClient snapshotDir = snapshot.GetDirectoryClient(directoryName);
    ShareFileClient snapshotFile = snapshotDir.GetFileClient(fileName);

    // Get a ShareDirectoryClient, then a ShareFileClient to the live file
    ShareDirectoryClient liveDir = share.GetDirectoryClient(directoryName);
    ShareFileClient liveFile = liveDir.GetFileClient(fileName);

    // Restore the file from the snapshot
    ShareFileCopyInfo copyInfo = await liveFile.StartCopyAsync(snapshotFile.Uri);

    // Display the status of the operation
    Console.WriteLine($"Restore status: {copyInfo.CopyStatus}");
}

刪除共用快照集

下列範例會刪除檔案共用快照集。

//-------------------------------------------------
// Delete a snapshot
//-------------------------------------------------
public async Task DeleteSnapshotAsync(string shareName, string snapshotTime)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Get a ShareClient
    ShareClient share = shareService.GetShareClient(shareName);

    // Get a ShareClient that points to a snapshot
    ShareClient snapshotShare = share.WithSnapshot(snapshotTime);

    try
    {
        // Delete the snapshot
        await snapshotShare.DeleteIfExistsAsync();
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
        Console.WriteLine($"Error code: {ex.Status}\t{ex.ErrorCode}");
    }
}

使用計量針對 Azure 檔案儲存體進行疑難排解

Azure 儲存體分析支援 Azure 檔案儲存體的計量。 利用度量資料,您可以追蹤要求及診斷問題。

您可以透過 Azure 入口網站啟用 Azure 檔案儲存體的計量。 您也可以透過 REST API 或 Azure 檔案儲存體用戶端程式庫中的其中一個同類工具來呼叫設定檔案服務屬性作業,以程式設計方式啟用計量。

下列程式碼範例會示範如何使用 .NET 用戶端程式庫,啟用 Azure 檔案儲存體的計量。

//-------------------------------------------------
// Use metrics
//-------------------------------------------------
public async Task UseMetricsAsync()
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Set metrics properties for File service
    await shareService.SetPropertiesAsync(new ShareServiceProperties()
    {
        // Set hour metrics
        HourMetrics = new ShareMetrics()
        {
            Enabled = true,
            IncludeApis = true,
            Version = "1.0",

            RetentionPolicy = new ShareRetentionPolicy()
            {
                Enabled = true,
                Days = 14
            }
        },

        // Set minute metrics
        MinuteMetrics = new ShareMetrics()
        {
            Enabled = true,
            IncludeApis = true,
            Version = "1.0",

            RetentionPolicy = new ShareRetentionPolicy()
            {
                Enabled = true,
                Days = 7
            }
        }
    });

    // Read the metrics properties we just set
    ShareServiceProperties serviceProperties = await shareService.GetPropertiesAsync();

    // Display the properties
    Console.WriteLine();
    Console.WriteLine($"HourMetrics.InludeApis: {serviceProperties.HourMetrics.IncludeApis}");
    Console.WriteLine($"HourMetrics.RetentionPolicy.Days: {serviceProperties.HourMetrics.RetentionPolicy.Days}");
    Console.WriteLine($"HourMetrics.Version: {serviceProperties.HourMetrics.Version}");
    Console.WriteLine();
    Console.WriteLine($"MinuteMetrics.InludeApis: {serviceProperties.MinuteMetrics.IncludeApis}");
    Console.WriteLine($"MinuteMetrics.RetentionPolicy.Days: {serviceProperties.MinuteMetrics.RetentionPolicy.Days}");
    Console.WriteLine($"MinuteMetrics.Version: {serviceProperties.MinuteMetrics.Version}");
    Console.WriteLine();
}

如果遇到任何問題,請參閱針對 Azure 檔案儲存體進行疑難排解

下一步

如需 Azure 檔案儲存體的詳細資訊,請參閱下列資源:

概念性文章和影片

檔案儲存體的工具支援

參考

如需使用已被取代之 .NET 11.x 版 SDK 的相關程式碼範例,請參閱使用 .NET 11.x 版的程式碼範例