Windows 8 – Copy file from Assets to Local Folder

When porting mobile apps to Windows 8, I immediately came across the same issue as each of the previous platforms, namely, how to copy my ‘starting’ data files into local storage where they can be modified.

In this case, I have a file in my Assets folder called ‘Prayers.xml’. At application startup I want to verify if the file already exists in the local store – if not, copy it from the Assets folder in the installation directory.

This is how you end up handling it in Windows 8.

        async void CopyPrayerFile()
        {
            //get the storage for your app 
            Windows.Storage.StorageFolder store = Windows.Storage.ApplicationData.Current.LocalFolder;
            StorageFile prayerFile = null;
            try
            {
                prayerFile = await store.GetFileAsync("Prayers.xml");
            }
            catch (System.IO.FileNotFoundException)
            {}

            if (prayerFile == null)
            {
                //get the file from Assets

                StorageFolder install = Windows.ApplicationModel.Package.Current.InstalledLocation;
                StorageFile installFile = await install.GetFileAsync("Assets\Prayers.xml");

                installFile.CopyAsync(store);   
            }
        }

I /thought/ I knew how to copy a file…

More trials and tribulations on the Android platform – which I love, don’t get me wrong.

I admit upfront that this is very likely my own fault for not knowing the ‘correct’ way to achieve my goal. It also may possibly have to do with some Android 1.5 behavior, as that is the standard I typically use for compatibility on simple apps. Anyway…

Today’s story begins with an xml file. More precisely, an xml file containing an RSS feed - to ‘preload’ an Android application with a backlog of blog posts stored locally on the device.

So, I store the xml file in the /raw folder in Eclipse, and use

rssInputStream = this.getResources().openRawResource(R.raw.feed);

to get the input stream, then proceed to loop through the file, writing to my output file in /data/data/<myPackage>/files/feed.xml (approximately 300kb file) which I will read and write from on future accesses.

It works great, sort of. In the following code to copy the file from the raw resource to my local feed.xml file:

while ((length = databaseInputStream.read(buffer)) != -1)
{
databaseOutputStream.write(buffer);
}

if the buffer is [1], everything works – but SLOWLY (obviously).

if the buffer is > [1] and < [size of the file], the file gets truncated in a weird (but consistent) position no matter what the buffer size is. It truncates in the same spot with different buffer sizes, so it doesn’t seem to be a buffer size/loop/overflow condition.

if the buffer == [size of the file], it works and is fast

if the buffer > [size of the file], it all gets copied, but I have to trim the end whitespace from the file or I get parsing problems later.

I swear I have tried a million different combinations of loop and copy conditions, and all seem to result in the same behavior. I even tried doing an extra read/write after the loop just to make sure there was nothing left behind in the stream…no dice. I tried at least 2-3 completely separate code examples to accomplish this…same result.

So, for now, since I know the size of the file I am deploying, I’m cheating and using buffer == size of file

And this serves as my reminder/documentation the next time I want to publish an updated version of the app with a new raw file…REMEMBER TO UPDATE THE BUFFER SIZE!