48

Is there any other way of checking whether a file exists in a Windows Store app?

try
{
    var file = await ApplicationData.Current.LocalFolder.GetFileAsync("Test.xml");
    //no exception means file exists
}
catch (FileNotFoundException ex)
{ 
    //find out through exception 
}
Robert MacLean
  • 38,975
  • 25
  • 98
  • 152
Haris Hasan
  • 29,856
  • 10
  • 92
  • 122

10 Answers10

26

According to the accepted answer in this post, there is no other way at the moment. However, the File IO team is considering changing the the api so that it returns null instead of throwing an exception.

Quote from the linked post:

Currently the only way to check if a file exists is to catch the FileNotFoundException. As has been pointed out having an explicit check and the opening is a race condition and as such I don't expect there to be any file exists API's added. I believe the File IO team (I'm not on that team so I don't know for sure but this is what I've heard) is considering having this API return null instead of throwing if the file doesn't exist.

keyboardP
  • 68,824
  • 13
  • 156
  • 205
  • 2
    I believe that the new IsAvailable property in Windows 8.1 addresses this. – satur9nine Sep 04 '13 at 17:52
  • @satur9nine - Thanks, that's good to know. I haven't had the chance to look into the 8.1 APIs yet. – keyboardP Sep 05 '13 at 21:08
  • 4
    ApplicationData.Current.LocalFolder.TryGetItemAsync(fileName) can do the trick now. No more ugly exception handling required. Please remember that this is also an awaitable call. – RBT Apr 06 '15 at 06:24
  • Unfortunately, that call doesn't exist for Windows Phone, so you're out of luck if you're building a Universal App for Windows 8.1/Windows Phone 8.1. I guess I'll just have to retarget my app to Windows 10.... – Levi Fuller Jun 22 '15 at 03:55
13

This may be old, but it looks like they've changed how they want you to approach this.

You're supposed to attempt to make the file, then back down if the file already exists. Here is the documentation on it. I'm updating this because this was the first result on my Google search for this problem.

So, in my case I want to open a file, or create it if it doesn't exist. What I do is create a file, and open it if it already exists. Like so:

save = await dir.CreateFileAsync(myFile, CreationCollisionOption.OpenIfExists);
Billdr
  • 1,557
  • 2
  • 17
  • 30
  • 4
    This only works if you are trying to create file with a unique name. If you are just checking for existence of the file then obviously you wouldn't want to do this. – chue x Jun 11 '13 at 13:09
8

I stumbled on to this blog post by Shashank Yerramilli which provides a much better answer.

I have tested this for windows phone 8 and it works. Haven't tested it on windows store though

I am copying the answer here

For windows RT app:

public async Task<bool> isFilePresent(string fileName)
 {
    var item = await ApplicationData.Current.LocalFolder.TryGetItemAsync(fileName);
    return item != null;
 }

For Windows Phone 8

 public bool IsFilePresent(string fileName)
 {
     return System.IO.File.Exists(string.Format(@"{0}\{1}", ApplicationData.Current.LocalFolder.Path, fileName);
 }

Check if a file exists in Windows Phone 8 and WinRT without exception

Jap
  • 651
  • 6
  • 16
  • "The type or namespace name 'File' does not exist in the namespace 'System.IO' (are you missing an assembly reference?)" – Mike Aug 07 '14 at 00:06
  • What app type are you trying to use it in : Windows Phone 8, or Windows RT App? – Jap Aug 07 '14 at 09:42
  • A universal Windows / Phone store app that targets 8.1. Also, while you're here: your WP8 function should just return a bool, and it doesn't need the async keyword either. – Mike Aug 07 '14 at 18:15
  • Thanks for letting me know about the correction, The 'File.Exists()' solution only works in Window phone 8. The 'localFolder.TryGetItem()' method will work in the Windows 8.1 part of the universal app. For windows phone 8.1 part: you can try the solution by Billdr http://stackoverflow.com/a/12116839/2335882. – Jap Aug 08 '14 at 10:39
  • The answer you linked to wouldn't work, as it returns a file whether it exists or not (because it creates it in the latter case). – Mike Aug 08 '14 at 17:02
  • Its weird that they removed the File.Exists() from windows phone 8.1, I guess right now the only way is to try to open the file & catch an exception. – Jap Aug 09 '14 at 09:46
3

You can use the old Win32 call like this to test if directory exist or not:

GetFileAttributesExW(path, GetFileExInfoStandard, &info);

return (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? false: true;

It works in Desktop and Metro apps: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946%28v=vs.85%29.aspx

Michael Wildermuth
  • 5,762
  • 3
  • 29
  • 48
  • Where does FILE_ATTRIBUTE_DIRECTORY come from here? I tested this function, and it works, but I don't see how. Thanks! – Justin R. May 23 '14 at 18:10
3

Microsoft has added a new function to StorageFile in Windows 8.1 to allow user engineers to determine if a file can be accessed: IsAvailable

satur9nine
  • 13,927
  • 5
  • 80
  • 123
2

The other means to check is by getting files in local folder

    var collection =  ApplicationData.Current.LocalFolder.GetFilesAsync() 

Using this method and then iterating over all the elements in the collection and check for its availability.

Robert MacLean
  • 38,975
  • 25
  • 98
  • 152
Anobik
  • 4,841
  • 2
  • 17
  • 32
1

I tried to write my own using old tricks:

  1. GetFileAttributesEx() always seems to end up with ERROR_ACCESS_DENIED if file selected via FileOpenPicker;
  2. Ditto for FindFirstFileEx();
  3. _stat() always ends up with ENOENT when file selected via FileOpenPicker;
  4. CreateFile2() with CREATE_NEW option works -- if file does exist it will fail with INVALID_HANDLE_VALUE return value and ERROR_FILE_EXISTS last error; if file does not exist you have to remember to delete created file afterwards.

All in all -- you're better of sticking with exception handling method.

1

8.1 got something like this, I tried it worked.

var folder = ApplicationData.Current.LocalFolder;
var file = await folder.TryGetItemAsync("mytext.txt") as IStorageFile;

if (file == null)
{
   //do what you want
}
else
{
   //do what you want
}

http://marcominerva.wordpress.com/2013/11/19/how-to-check-if-a-file-exists-in-a-windows-8-1-store-apps-no-more-exception-handling/

canbax
  • 3,432
  • 1
  • 27
  • 44
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Andrey Korneyev Nov 27 '14 at 07:55
1
    Dim myPath As StorageFolder
    If (From i In Await KnownFolders.MusicLibrary.GetFoldersAsync() Where i.Name = "PodBong").Count = 1 Then
        myPath = Await KnownFolders.MusicLibrary.GetFolderAsync("PodBong")
    Else
        myPath = Await KnownFolders.MusicLibrary.CreateFolderAsync("PodBong")

    End If
HippieGeek
  • 11
  • 1
0

The documentation for TryGetItemAsync says, "This example shows how to checkfor the existence of a file." It seems that this API is officially intended to serve that purpose.

Thaine Norris
  • 75
  • 1
  • 7