Below is the code I used to access the asset file for a metro app I am working on.
async void readFileFromDisk (string fileName, string fileType)
{
string fileContent;
StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(fileName);
using (IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read))
{
using (DataReader dataReader = new DataReader(readStream))
{
UInt32 numBytesLoaded = await dataReader.LoadAsync((UInt32)readStream.Size);
fileContent = dataReader.ReadString(numBytesLoaded);
}
}
This code is run in the handler for Loaded event for the page. I am currently getting an exception saying “Value does not fall in range”. The error occurs at the first line itself, where I try to get storagefile handle from the installation folder.
On debugging, the fileName string comes out to be Null. I guess, I should be moving the code to some event which is fired at a later stage in page lifecycle, but can’t seem to figure out what is the best place to do it. Suggestions??
P.S. I need to read this file before any interaction from user, as it reads the data for the level, that user will be interacting with.
Edit:
Missed a couple things.
The below function is called from the handler for loaded event.
void Game_Loaded(object sender, RoutedEventArgs e)
{
//read all level files to the strings
readFileFromDisk("//Assets/Levels/Start" + selectedLevel + ".txt", "Start");
This handler basically calls above function for different file paths, in similar manner. The string selected level is static variable, while the fileName string is created from the same.
Edit 2:
Found the issue, but solution is still far away. The return type of readFileFromDist method is causing trouble. Changed it to Task, and this part works fine, but I get “Object reference not set to an instance” error. Tried to convert Game_Loaded event handler to async too, to use await operators, but that gives me compiler error for “wrong return type”.
SO, I tried removing async completely, but I guess I can’t do that. There is no way to open files without using async function. So, I essentially need a way to call the readFileFromDisk function, using await, and continue with rest of the code execution once the task is completed. Something like, “IsCompleted” event for the awaited calls for the function.
Solved! Needed to use “ms:appx///Assets/filename.txt” instead of “//Assets/filename.txt”.