Wednesday, 18 July 2018

Part 3: Using Azure Storage API With A File Share

In my previous post I discussed how to create your file share and add some files to it using Powershell. In this post I will show you how to use the Azure Storage API to manipulate your file share.
Scenarios where this would be useful.
  • On-premise applications.
  • Accessing the share from Azure but in different regions than the one where your share is residing.
  •  Using the share in scenarios where you cannot mount file shares like Azure websites.
I am going to explore the first scenario and change one of my existing on-premise applications to use Azure file service instead of the local file system. This is actually a quick change since the application performs file operations using a file repository class not the System.IO classes directly. I initially did this to make the code unit testable and now it is also making it easy to swap out my current implementation for the Azure file service one.
The Code
The easiest way to install the Windows Azure Storage client library is using the Nuget package manager console:

Install-Package WindowsAzure.Storage
It can also be obtained when you install Azure SDK for .NET, which I can recommend if you are going to do any Azure development. After installing add the following imports:

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.File;

Connecting to your storage account
var conString = "DefaultEndpointsProtocol=https;
AccountName=YourAccountName;AccountKey=YourStorageAccountAccessKey";
var storageAccount = storageAccount.Parse(conString);
var fileClient = storageAccount.CreateCloudFileClient();

Creating a new  share
var newShare = fileClient.GetShareReference("NewShareName");
newShare.CreateIfNotExistsAsync().Wait();
Listing the contents of existing shares
var ExistingShare = fileClient.GetShareReference("ExistingShareName");
shareRoot = ExistingShare.GetRootDirectoryReference();
var contents = shareroot.ListFilesAndDirectories();
var existingfile = shareRoot.GetFileReference("FileInRootDir");
var existingDirectory = shareRoot.GetDirectoryReference("DirectoryInRootDir");
Note contents is of type IEnumerable<IListFileItem> and contains files of type CloudFile as well as directories of type CloudFileDirectory both implement the IListFileItem interface.
Creating files and directories
shareRoot = fileshare.GetRootDirectoryReference();
shareRoot.GetFileReference("NewFileName").Create(NewFileSize);
shareRoot.GetDirectoryReference("NewDirectoryName").Create();

Downloading a file
//To a local file
existingfile.DownloadToFile("LocalFilePath", FileMode.Create);
Read a file
//Read the contents of a text file into a string
string fileContents = existingfile.DownloadText();
//Read bytes from a file into byte array
var fileContents = existingfile.DownloadToByteArray(byteArray,offset);
Retrieve a directory or file directly
As you can see it will be very cumbersome to walk down a shares’ directory hierarchy to retrieve files. You can gain access to a file or directory directly by using its URI property. It will look something like this:
https://YourAccount.file.core.windows.net/ShareRootDir/1stDir/SubDir/FileName

And you can use it in the following way:
var fileUri = new Uri(FullURI, UriKind.Absolute);
var azfile = new CloudFileDirectory(fileUri , fileClient.Credentials);

It might take a bit of time to wrap your head around the fact that the API is using the CloudFileDirectory type that represents both files and directories. If you want to work with files only you can list them using the following snippet:
SomeAzurefolder.ListFilesAndDirectories().OfType<CloudFile>()
The examples above are for demonstration only, in production you would be better of using async versions of these methods and streaming files up or down instead of reading whole files into memory.

No comments:

Post a Comment