Windows Azure Local File Storage – How To Guide and Warnings

By Jim White (Intertech Director of Training and Instructor)

In general, Microsoft has tried to make writing Web applications for the Azure platform akin to writing for your local IIS environment.  In fact, Microsoft lists "use your existing development skills to build cloud applications" on the Azure Web site as one of its major selling points.  I think, to a large extent, .NET developers will find building or moving an application to Azure straightforward.  However, to be fair, there are also a number of areas where the application will change to deal with the reality of this new platform and, more generally, cloud computing.  One of those areas is simple file access and/or local storage.

File Access in the "Normal" ASP.NET world

For example sake, say you needed to read/write from a simple text file.  Perhaps you need to read some configuration information from the file, or perhaps some SQL that you need to execute was in the file.  Whatever the reason, accessing this file is pretty straightforward.  In a "normal" ASP.NET application, accessing a file that is stored on a virtual path on the Web server is quite simple and might look like the code below (in C#).

    //———————– read config contents ——————————–
    try
    {
        string s = System.IO.File.ReadAllText(Server.MapPath("myConfigs") + "myFile.txt");
        //… do your work with s
    }
    catch (Exception myException)
    {
       …    }

    //———————– write config contents ——————————–
    if (!text.Equals(""))
    {
        System.IO.File.WriteAllText(Server.MapPath("myConfigs") + "myFile.txt", text);
    }
    else
    {
        System.IO.File.WriteAllText(Server.MapPath("myConfigs") + "myFile.txt", "no data");
    }

File Access in the Cloud

Now, how would that look in the cloud?  Well, first you must step back and consider that local storage in the cloud is not the same as that under our local IIS environment.  Local storage, is assumed under an ASP.NET application running on a local IIS server.  In the Azure world, you must first configure your role to request local storage as it is deployed.  This can be done with the Role Editor in VS 2008.  The Local Storage tab on the editor allows you to specify the name, size and clean/role policy for the storage as shown below.

image The information from this editor is stored in the service definition file of the role and used to configure the Azure environment when the application is published to the cloud.

Local Storage Location

So now you have local storage, but where is it?  When you deploy your application (consisting of either a web or worker role) to Azure, a storage area is assigned to your application.  The exact location is at the Azure servers discretion.  The physical path of the folder for your assigned storage can be located through the Azure API.  In this case, request the location of your local storage through, Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.  The RoleEnvironment class represents the Azure environment that your instance of your role (web or worker) is running in.  So, reading and writing to that file might look something like the following code in an Azure world.

    //———————– read config contents in Azure ———————–
    try
    {

            LocalResource myConfigsStorage = RoleEnvironment.GetLocalResource("myConfigs");

        string s = System.IO.File.ReadAllText(myConfigStorage.RootPath + "myFile.txt");
        //… do your work with s
    }
    catch (Exception myException)
    {
        …    }

    //———————– write config contents in Azure————————
    if (!text.Equals(""))
    {

           LocalResource myConfigsStorage = RoleEnvironment.GetLocalResource("myConfigs");

        System.IO.File.WriteAllText(myConfigStorage.RootPath + "myFile.txt", text);
    }
    else
    {
        System.IO.File.WriteAllText(myConfigStorage.RootPath + "myFile.txt", "no data");
    }

Easy enough you say.  Yes, the API is straightforward enough so as to appease most .NET developers.  However, a bigger issue with regard to this local storage must be considered.

Local Storage is Temporary and Instance Relative in the Cloud

Local storage, like that just used in the example to read/write text to myFile.text is temporary in Azure!  So, if the virtual machine supporting your role dies and cannot recover, your local storage is lost!  Therefore, Azure developers will tell you, only volatile data should ever be stored in local storage of Azure.  Furthermore, I eluded earlier to the fact that the storage was per instance of a role.  Importantly, local storage is not shared across multiple role instances.  Usually, people move applications to the cloud to take advantage of the scalability and redundancy multiple instances provide.  But these instances each have their own local storage and cannot access each others.  If the data in the local storage is changing and must be shared, you need to rethink the application design.

Local Storage Alternatives

If you need to read/write data in the cloud in a non-volatile and shared way , take advantage of Azure’s storage options:  blobs, table storage, queues and SQL Azure databases.  My co-worker Tim Star (Microsoft MVP) has described them in his blog post here.  This may require some application re-architecting, but in the end, your application will run better, stronger, faster in the Azure cloud.

  • Eman

    Hello
    I have done the same steps but it didn't work with me
    I read from a file using InputStream .
    I have wrote this code below

    LocalResource myConfigsStorage = RoleEnvironment.GetLocalResource("LocalStorage1");

    StreamReader sr = new StreamReader(File.OpenRead(myConfigsStorage.RootPath + "MyFile.csv"), Encoding.Default, true);

    what should I do??

  • Iggie

    wHAT’S WRONG WITH USING SERVER.MAPPATH()? iT WOULD HAVE THE BENEFIT OF A MORE PERMANENT LOCATION UNDER AZURE EMULATOR; WHILE DEVELOPING LOCALLY LOCAL STORAGE LOCATIONS MUST BE CREATED/FLUSHED ON THE FLY WITH EACH START/STOP, BUT A LOCAL LOCATION REFERENCED WITH SERVER.MAPPATH() IS FIXED.

{Offer-Title}

{Offer-PageContent}
Click Here