使用 .NET 開發 Azure 檔案服務
了解開發使用 Azure 檔案儲存體來儲存資料的 .NET 應用程式基本概念。 本文說明如何建立簡單的主控台應用程式,以使用 .NET 和 Azure 檔案儲存體來執行下列作業:
- 取得檔案的內容。
- 設定檔案共用的大小上限或配額。
- 建立檔案的共用存取簽章 (SAS)。
- 將檔案複製到相同儲存體帳戶中的另一個檔案。
- 將檔案複製到相同儲存體帳戶中的 Blob。
- 建立檔案共用的快照集。
- 從共用快照集還原檔案。
- 使用 Azure 儲存體計量進行疑難排解。
若要深入了解 Azure 檔案儲存體,請參閱什麼是 Azure 檔案儲存體?
適用於
檔案共用類型 | SMB | NFS |
---|---|---|
標準檔案共用 (GPv2)、LRS/ZRS | ||
標準檔案共用 (GPv2)、GRS/GZRS | ||
進階檔案共用 (FileStorage)、LRS/ZRS |
了解 .NET API
Azure 檔案服務會提供兩種廣泛的方法給用戶端應用程式:伺服器訊息區 (SMB) 和 REST。 在 .NET 中,System.IO
和 Azure.Storage.Files.Shares
API 會將這些方法抽象化。
API | 使用時機 | 備註 |
---|---|---|
System.IO | 您的應用程式:
|
使用 Azure 檔案儲存體透過 SMB 實作的檔案 I/O,通常是與使用任何網路檔案共用或本機儲存裝置的 I/O 相同。 如需 .NET 中許多功能的簡介,包括檔案 I/O,請參閱主控台應用程式教學課程。 |
Azure.Storage.Files.Shares | 您的應用程式:
|
本文示範使用 REST (而不是 SMB) 的檔案 I/O Azure.Storage.Files.Shares 用法和管理檔案共用。 |
建立主控台應用程式並取得組件
您可以在任何類型的 .NET 應用程式中使用 Azure 檔案儲存體用戶端程式庫。 這些應用程式包括 Azure 雲端、Web、桌面和行動應用程式。 在本指南中,為求簡化,我們會建立主控台應用程式。
在 Visual Studio 中,建立新的 Windows 主控台應用程式。 下列步驟說明如何在 Visual Studio 2019 中建立主控台應用程式。 這些步驟類似其他 Visual Studio 版本中的步驟。
- 啟動 Visual Studio 並選取 [建立新專案]。
- 在 [建立新專案] 中,針對 C# 選擇 [主控台應用程式 (.NET Framework)],然後選取 [下一步]。
- 在 [設定新專案] 中,輸入應用程式的名稱並選取 [建立]。
將本文中的所有程式碼範例新增至 Program.cs 檔案中的 Program
類別。
使用 NuGet 來安裝必要的封裝
請在您的專案中參考這些套件:
- 適用於 .NET 的 Azure 核心程式庫:此套件是 Azure 用戶端管線的實作。
- 適用於 .NET 的 Azure 儲存體 Blob 用戶端程式庫:此套件可供以程式設計方式存取儲存體帳戶中的 Blob 資源。
- 適用於 .NET 的 Azure 儲存體檔案用戶端程式庫:此套件可供以程式設計方式存取儲存體帳戶中的檔案資源。
- 適用於 .NET 的 System Configuration Manager 程式庫:此套件可供類別在組態檔中儲存和擷取值。
您可以使用 NuGet 來取得套件。 執行下列步驟:
在 [方案總管] 中,以滑鼠右鍵按一下您的專案並選擇 [管理 NuGet 套件]。
在 [NuGet 套件管理員] 中,選取 [瀏覽]。 然後搜尋並選擇 Azure.Core,然後選取 [安裝]。
此步驟會安裝套件及其相依性。
搜尋並安裝這些封裝:
- 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 版的程式碼範例。