A simplified, modern .NET client library for Azure File Share (Azure Files) with built-in retry policies, comprehensive error handling, and intuitive APIs.
Simplified API - Easy-to-use wrapper around Azure.Storage.Files.Shares SDK Built-in Resilience - Automatic retry policies using Polly File Share Management - Create, delete, and list shares Directory Operations - Create, delete, and navigate directories File Operations - Upload, download, copy, and delete files Streaming Support - Efficient handling of large files Metadata Management - File and directory metadata support SAS Token Generation - Secure delegated access Comprehensive Error Handling - Detailed exception information Extensive Documentation - Full XML documentation for IntelliSense
dotnet add package AzureStorage.Standard.FilesOr via Package Manager Console:
Install-Package AzureStorage.Standard.Filesusing AzureStorage.Standard.Files;
using AzureStorage.Standard.Core;
var options = new StorageOptions
{
ConnectionString = "DefaultEndpointsProtocol=https;AccountName=..."
};
var fileClient = new FileShareClient(options);await fileClient.CreateShareIfNotExistsAsync("documents");// Upload from local file
await fileClient.UploadFileAsync(
shareName: "documents",
filePath: "reports/annual-report.pdf",
localFilePath: "C:\\reports\\2024-annual-report.pdf"
);
// Upload from stream
using var stream = File.OpenRead("data.csv");
await fileClient.UploadFileAsync(
shareName: "documents",
filePath: "data/data.csv",
stream: stream
);// Download to local file
await fileClient.DownloadFileAsync(
shareName: "documents",
filePath: "reports/annual-report.pdf",
localFilePath: "C:\\downloads\\annual-report.pdf"
);
// Download to stream
using var downloadStream = await fileClient.DownloadFileToStreamAsync(
shareName: "documents",
filePath: "data/data.csv"
);// Create directory
await fileClient.CreateDirectoryIfNotExistsAsync(
shareName: "documents",
directoryPath: "reports/2024"
);
// List directory contents
var files = await fileClient.ListFilesAndDirectoriesAsync(
shareName: "documents",
directoryPath: "reports"
);
foreach (var item in files)
{
if (item.IsDirectory)
Console.WriteLine($"Directory: {item.Name}");
else
Console.WriteLine($"File: {item.Name}, Size: {item.Size} bytes");
}
// Delete directory
await fileClient.DeleteDirectoryAsync(
shareName: "documents",
directoryPath: "reports/2024"
);// Set file metadata
var metadata = new Dictionary<string, string>
{
{ "Author", "John Doe" },
{ "Department", "Finance" },
{ "Year", "2024" }
};
await fileClient.SetFileMetadataAsync(
shareName: "documents",
filePath: "reports/annual-report.pdf",
metadata: metadata
);
// Get file metadata
var fileMetadata = await fileClient.GetFileMetadataAsync(
shareName: "documents",
filePath: "reports/annual-report.pdf"
);// Copy file within the same share
await fileClient.CopyFileAsync(
shareName: "documents",
sourceFilePath: "original.pdf",
destinationFilePath: "backup/original-copy.pdf"
);// Get file properties (size, last modified, etc.)
var properties = await fileClient.GetFilePropertiesAsync(
shareName: "documents",
filePath: "reports/annual-report.pdf"
);
Console.WriteLine($"Size: {properties.Size} bytes");
Console.WriteLine($"Last Modified: {properties.LastModified}");
Console.WriteLine($"Content Type: {properties.ContentType}");bool fileExists = await fileClient.FileExistsAsync(
shareName: "documents",
filePath: "reports/annual-report.pdf"
);
if (fileExists)
{
Console.WriteLine("File exists!");
}await fileClient.DeleteFileAsync(
shareName: "documents",
filePath: "reports/old-report.pdf"
);// List all shares
var shares = await fileClient.ListSharesAsync();
foreach (var share in shares)
{
Console.WriteLine($"Share: {share}");
}
// Check if share exists
bool exists = await fileClient.ShareExistsAsync("documents");
// Get share properties
var properties = await fileClient.GetSharePropertiesAsync("documents");
Console.WriteLine($"Quota: {properties.QuotaInGB} GB");
// Delete share
await fileClient.DeleteShareAsync("documents");// Generate SAS token for a file
var sasToken = await fileClient.GenerateFileSasTokenAsync(
shareName: "documents",
filePath: "reports/annual-report.pdf",
permissions: ShareFileSasPermissions.Read,
expiresOn: DateTimeOffset.UtcNow.AddHours(24)
);
// Use the SAS URL
var sasUrl = $"https://myaccount.file.core.windows.net/documents/reports/annual-report.pdf?{sasToken}";var options = new StorageOptions
{
ConnectionString = "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=..."
};var options = new StorageOptions
{
AccountName = "myaccount",
AccountKey = "your-account-key"
};var options = new StorageOptions
{
ServiceUri = new Uri("https://myaccount.file.core.windows.net")
};// Create nested directory structure
await fileClient.CreateDirectoryIfNotExistsAsync("documents", "reports");
await fileClient.CreateDirectoryIfNotExistsAsync("documents", "reports/2024");
await fileClient.CreateDirectoryIfNotExistsAsync("documents", "reports/2024/Q1");
// Upload file to nested directory
await fileClient.UploadFileAsync(
shareName: "documents",
filePath: "reports/2024/Q1/financial-report.pdf",
localFilePath: "C:\\reports\\Q1-report.pdf"
);Use forward slashes for paths:
// Correct
"reports/2024/Q1/report.pdf"
// Incorrect
"reports\\2024\\Q1\\report.pdf"Ensure parent directories exist before uploading:
await fileClient.CreateDirectoryIfNotExistsAsync("documents", "reports/2024");
await fileClient.UploadFileAsync("documents", "reports/2024/report.pdf", localPath);For files > 100 MB, use streaming:
using var fileStream = File.OpenRead(largeFilePath);
await fileClient.UploadFileAsync("documents", "large-file.zip", fileStream);Azure Files supports SMB protocol - mount as network drive:
# Windows
net use Z: \\myaccount.file.core.windows.net\documents /u:AZURE\myaccount accountkey
# Linux
sudo mount -t cifs //myaccount.file.core.windows.net/documents /mnt/documents -o username=myaccount,password=accountkeyReplace on-premises file shares with Azure Files:
// Migration pattern
await fileClient.CreateShareIfNotExistsAsync("legacy-app-data");
await fileClient.UploadFileAsync("legacy-app-data", "config/settings.ini", localPath);Store application configuration files:
await fileClient.UploadFileAsync("config", "appsettings.json", configPath);
var configStream = await fileClient.DownloadFileToStreamAsync("config", "appsettings.json");Centralized logging:
var logPath = $"logs/{DateTime.UtcNow:yyyy-MM-dd}/app.log";
await fileClient.UploadFileAsync("logs", logPath, logFilePath);- .NET Standard 2.0
- .NET Standard 2.1
- .NET 8.0
- .NET 9.0
try
{
await fileClient.DownloadFileAsync("documents", "missing-file.pdf", "output.pdf");
}
catch (AzureStorageException ex)
{
Console.WriteLine($"Error: {ex.Message}");
Console.WriteLine($"Error Code: {ex.ErrorCode}");
Console.WriteLine($"Status Code: {ex.StatusCode}");
}- AzureStorage.Standard.Blobs - Azure Blob Storage client
- AzureStorage.Standard.Tables - Azure Table Storage client
- AzureStorage.Standard.Queues - Azure Queue Storage client
For complete documentation, visit the GitHub repository.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
For issues, questions, or suggestions, please open an issue on GitHub.