Those unfamiliar to Windows Store development will be both confused and relieved by the implementation of local storage in universal Windows apps.
Windows Phone Silverlight developers may have had a difficult experience implementing a good local storage model in their apps. Having to open and write to files in Isolated Storage wasn't one of the easiest tasks to do but thankfully, this model was improved in Windows Store development with the introduction of the StorageFile and StorageFolder and with universal app development, you have these to leverage in your apps.
Choosing the folder
Saving files into local storage is basically a matter of saving a file into a folder somewhere on disk. Your app will already expose the root folders that you can read and write to through ApplicationData.Current.
These folders are:
- ApplicationData.Current.LocalFolder;
- ApplicationData.Current.RoamingFolder;
- ApplicationData.Current.TemporaryFolder;
For the most part, you'll only want to use the LocalFolder. If you want to add an extra step in the process for saving into local storage, you have the TemporaryFolder that is cleared when the user exits your app.
You can also create your own folders underneath these root folders that you can use to store and retrieve certain pieces of data. To do this, you get the root folder you want like so:
- var folder = ApplicationData.Current.LocalFolder;
Then you can call CreateFolderAsync on that folder to create a new folder. You pass in the name you want your folder to be called and optionally, you can provide a CreationCollisionOption. Although it is an option, I highly recommend doing so to prevent your app from throwing a fit if you're creating a folder that already exists. You can do this as follows:
- var folder = ApplicationData.Current.LocalFolder;
- var newFolder = await folder.CreateFolderAsync("NewFolder", CreationCollisionOption.OpenIfExists);
Now we have folders set up, let's have a look at saving some files into them.
Saving TextSaving text into your storage folder is a very straight forward task.
FileIO is a class that provides helper methods for reading and writing to StorageFiles. One of these methods is WriteTextAsync that takes your StorageFile and string of text as parameters.
You can easily implement this by creating a new StorageFile with the folder you've created as follows:
- var textFile = await newFolder.CreateFileAsync("text.txt");
- await FileIO.WriteTextAsync(textFile, "Hello World!");
Now we will look at retrieving that file.
Getting FilesTo retrieve a file from a folder is very easy as long as you know the name of the file you've created within that folder.
To retrieve all the possible files within a folder, you can call the GetFilesAsync method on your folder.
- var files = await newFolder.GetFilesAsync();
To then find your desired file within that collection, you'll want to write a simple LINQ expression to locate it as follows:
- var desiredFile = files.FirstOrDefault(x => x.Name == "text.txt");
If you're unfamiliar with the FirstOrDefault method, it returns the file from the collection if it can be found otherwise it will return null. You'll need to provide checks to ensure the file was found so that your application doesn't throw exceptions when you attempt to open the file.
Now that we have our file, you're probably asking "How do I get the text out though?". Well we use the FileIO class again to read the text out to a string.
- var textContent = await FileIO.ReadTextAsync(desiredFile);
At this point, I've taught you the fundamentals of saving and loading into storage. Saving text isn't the only option that FileIO provides for saving into StorageFiles however. There is another option for saving a byte array into a file. This is useful for when you want to be storing media within your local storage in your app that hasn't been captured with any of the WinRT specific APIs. I will cover this in the next section.
Saving MediaThere are many ways of capturing media within your application. You have MediaCapture that allows you to capture photos, videos and audio. All of these kindly save themselves into a StorageFile that you need to provide from your local folder as I said before. The CreateFileAsync method allows you to create a file with any extension, however the APIs you're hooking into need to be able to understand that file.
Using MediaCapture, you'll need to provide the extension to the CreateFileAsync method that is associated with that media type. For example, creating a photo you would choose to capture to a JPEG file. With a video, you'd opt for a MP4 file and so on.
That's all there is too it folks. Explore some of the features in WinRT and you'll find that you'll be able to save to StorageFiles that you can create in your own local storage folders within your app to retrieve later.
You can grab a sample helper class in the attached Zip files that you can use in your own applications.
If you have any questions, feel free to leave a comment and I will get back in touch!