Finding if StorageFile is in StorageFolder in Windows 8 Apps

When developing Windows 8 Apps, it is likely you will come across issues when dealing with files. This is because Windows 8 Apps are in a sandboxed environment, and access to files on the system are particularly limited. One oversight I believe has been made in all this is when dealing with paths of a StorageFile you have access to. It seems that in winrt it is believed that you have no need to know where a file is, only that you have access to it, so a lot of helpful methods do not exist within winrt.

The Problem

I had an issue being caused where I was copying a file to a folder. The folder may already have a file of the same name, so I set up collision options for that situation. However it was also possible the file I was copying was already in that folder, and obviously this would throw an error (You can’t copy a file over itself). So I needed a way to check whether the folder contained the file I was attempting to copy before I attempted the operation. Unfortunately there is no  StorageFolder.ContainsFile(StorageFile) method for me to use, so I went searching for a solution.

A Solution – Take 1

The closest solution I found was an answer by Iris Classon on StackOverflow (Iris also has an excellent blog you can find here, especially check out her 365 “Stupid” Questions).  Unfortunately this uses try/catch for program flow, which is great, but I agree it’s probably the best solution for finding whether a folder contains a file with a particular filename. However this didn’t quite solve my problem, as this was checking if a file with a particular filename exists in the folder, and not whether it was the exact same file as the file I would like to save, so I modified the code a bit for my own purposes which can be seen below:

This is an extension method, so it will be added to the methods we can call on StorageFolders. If you want to know more about extension methods (they are wonderful things), see the MSDN documentation. This code first attempts to open our file by filename from the folder. We know that if we can’t find the file by filename, it is not in the folder, so the catch (an exception would be thrown if the GetFileAsync fails), returns false. Once we have opened the file (if we can), we then check it against our current file, using the FolderRelativeId, as these will also match if they are the same file, and will be different if the two files are located in different folders.

A Second (Better) Solution

As I said though, this uses try / catch for program flow, and this is not ideal. We also have to open the file again, which is slower than we need to be, and we are also creating an Async function which isn’t really required here. However there is a better solution. First we can create a GetDirectory extension method on StorageFile:

The function is simple, replace the filename, and preceeding slashes from the Path of the file, and we have the directory. Now it should be simple to perform our functionality:

As we now can retrieve the Directory from the file, we can just compare this directly to the path of the folder. I believe this should work in every situation, however I have provided both solutions just in case someone can think of a situation where the second would not work. I have made the file that contains these extension methods available for download below:

Extension Methods 186.4 KB

NOTE: A colleague of mine pointed out the helpful remark on the MSDN Documentation for StorageFile.Path:

Do not rely on this property to access a file because some files may not have file-system paths. For example if the file is backed by a URI, or was picked using the file picker, the file is not guaranteed to have a file-system path.

This means there might be the odd situation where this does not work, and Solution 1 is perhaps the more robust solution. However I have yet to come across the lack of a Path for a file, whether I’ve used the file picker, or directly accessed the file in code. So I guess the solution is down to personal preference here.

Summary

So if you would like to find a file with a particular filename exists in a folder, see Iris Classon’s answer on StackOverflow. However if you, like me, you may be copying over a file, and need to check you are not attempting to overwrite a file with itself to prevent critical exceptions from being thrown, then the two extension methods above are your best option. Feel free to download the code and use in your own projects if you find use for this.

Leave a Reply