26

I am currently working on a Windows 10 UWP App. The App needs to Check if a certain PDF File exists called "01-introduction", and if so open it. I already have the code for if the file does not exist. The Code Below is what i currently have:

        try
        {
            var test = await DownloadsFolder.CreateFileAsync("01-Introduction.pdf", CreationCollisionOption.FailIfExists); 
        }
        catch
        {

        }

This code Does not work correctly because to check if the file exists here, I attempt to create the file. However if the file does not already exist an empty file will be created. I do not want to create anything if the file does not exist, just open the PDF if it does.

If possible, i would like to look inside a folder which is in the downloads folder called "My Manuals".

Any help would be greatly appreciated.

James Tordoff
  • 661
  • 1
  • 5
  • 25
  • Is the "Swift Manuals" folder created by your app? By default, your app can only access files and folders in the user's Downloads folder that your app created. However, you can gain access to files and folders in the user's Downloads folder by calling a file picker ([FileOpenPicker](https://msdn.microsoft.com/library/windows/apps/br207847) or [FolderPicker](https://msdn.microsoft.com/library/windows/apps/br207881)) so that users can navigate and pick files or folders for your app to access. – Jay Zuo May 11 '16 at 02:12
  • @JayZuo-MSFT Thank you for the clarification Jay. This is the problem we have been coming across. So we can get directory access to Downloads. We need to look at another approach and do a little more reading. – James Tordoff May 11 '16 at 09:20
  • If you create a file or folder in the Downloads folder, we recommend that you add that item to your app's [FutureAccessList](https://msdn.microsoft.com/library/windows/apps/br207457) so that your app can readily access that item in the future. For more info, please see [File access permissions](https://msdn.microsoft.com/en-us/windows/uwp/files/file-access-permissions). – Jay Zuo May 11 '16 at 09:43

13 Answers13

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

But not support Win8/WP8.1

https://blogs.msdn.microsoft.com/shashankyerramilli/2014/02/17/check-if-a-file-exists-in-windows-phone-8-and-winrt-without-exception/

lindexi
  • 4,182
  • 3
  • 19
  • 65
9

There are two methods

1) You can use StorageFolder.GetFileAsync() as this is also supported by Windows 8.1 and WP 8.1 devices.

try
{
   StorageFile file = await DownloadsFolder.GetFileAsync("01-Introduction.pdf");
}
catch
{
    Debug.WriteLine("File does not exits");
}

2) Or you can use FileInfo.Exists only supported for windows 10 UWP.

FileInfo fInfo = new FileInfo("01-Introduction.pdf");
if (!fInfo.Exists)
{
    Debug.WriteLine("File does not exits");
}
AbsoluteSith
  • 1,917
  • 25
  • 60
  • 4
    Unfortunately (1) does not seem available within Windows 10 UWP there is no Definition ofr GetFileAsync for DownloadsFolder. (2) seems to be just what I am looking for, unfortunately I always return False, how do I specify which folder is to be searched for the FileInfo. I am only supporting Win10 and not backwards compatible at all. – James Tordoff May 10 '16 at 09:43
  • Are you sure DownloadFolder is a StorageFolder type, if so it should have a definition. Try pasting your entire code, I'll check it out – AbsoluteSith May 10 '16 at 11:22
  • DownloadFolder doesnt have GetFileAsync () method – Archana May 10 '16 at 11:53
  • 2
    If you're going to use `System.IO` at all, you might as well use `System.IO.File.Exists(String)`. It's more efficient - no need to construct an object - and simpler to read. – CBHacking Oct 04 '17 at 00:52
3

System.IO.File.Exists is UWP way too. I test now in Windows IOT. it just works.

Zen Of Kursat
  • 2,672
  • 1
  • 31
  • 47
  • No, it only works in LocalFolder, LocalCache, etc. Even if you grant access to another folder/file using the picker, or use a special folder (like Downloads in the question) the System.IO methods won't work there. – Sean O'Neil Mar 02 '22 at 02:25
2

This helped me in my case:

ApplicationData.Current.LocalFolder.GetFileAsync(path).AsTask().ContinueWith(item => { 
    if (item.IsFaulted)
        return; // file not found
    else { /* process file here */ }
});
2
public override bool Exists(string filePath)
    {
        try
        {
            string path = Path.GetDirectoryName(filePath);
            var fileName = Path.GetFileName(filePath);
            StorageFolder accessFolder = StorageFolder.GetFolderFromPathAsync(path).AsTask().GetAwaiter().GetResult();
            StorageFile file = accessFolder.GetFileAsync(fileName).AsTask().GetAwaiter().GetResult();
            return file != null;
        }
        catch
        {
            return false;
        }
    }
Idemax
  • 2,712
  • 6
  • 33
  • 66
Ali Yousefi
  • 2,355
  • 2
  • 32
  • 47
2

This worked for me running my UWP C# app on Windows 10...

    StorageFolder app_StorageFolder = await StorageFolder.GetFolderFromPathAsync( @App.STORAGE_FOLDER_PATH );
    var item = await app_StorageFolder.TryGetItemAsync(relative_file_pathname);
    return item != null;
Doug Null
  • 7,989
  • 15
  • 69
  • 148
0

You can use System.IO.File. Example:

// If file located in local folder. You can do the same for other locations.
string rootPath = ApplicationData.Current.LocalFolder.Path;
string filePath = Path.Combine(rootPath, "fileName.pdf");

if (System.IO.File.Exists(filePath))
{
    // File exists
}
else
{
    // File doesn't exist
}
Sapan Ghafuri
  • 545
  • 3
  • 13
  • 2
    While not "the UWP way" (in particular, it does an I/O operation - albeit a very fast one - synchronously), this is a viable option on UWP (Win10) apps. Just be aware that the app will not have any kind of lock on the file; if another thread or process removes or creates the file between check and use, you could get unexpected (and potentially harmful) behavior. – CBHacking Oct 04 '17 at 00:53
  • @CBHacking This is actually not true. It only works in the app's LocalFolder (and probably LocalCache and Temp). Even if you have access to another folder using the picker or a capability, System.IO stuff won't work there. – Sean O'Neil Mar 02 '22 at 02:19
  • @SeanO'Neil That's false for a few reasons. First, you can absolutely use `System.IO.File` to access files outside the app storage, such as in the system directory or, with the right capabilities defined, locations such as removable storage. Second, you can test for existence of files you can't even access; you'll get a different error for "file not found" vs. "access denied". Third, even if if checking app-specific files, an appcontainer can have multiple processes (e.g. background audio process) and any process can have multiple threads, so you do risk TOCTOU bugs. – CBHacking Mar 02 '22 at 10:03
  • 1
    ... Well. At some point they decided to make Access Denied errors return false for `File.Exists()`, which is a lie. You *CAN* still (I just checked) try to open or stat the file (`File.GetFileAttributes()` works even if you don't have read permissions; so does opening the file without requesting any access but you can't do that using `System.IO.File`). That will either work or throw an exception; FileNotFound or DirectoryNotFound mean the file doesn't exist, UnauthorizedAccess means it does. – CBHacking Mar 02 '22 at 10:37
  • @CBHacking Yeah File.Exists, EnumerateFiles, etc. hasn't worked as long as I remember. Perhaps as you say it used to. I forgot to mention it does, however, work on exFAT file systems, just not on NTFS. – Sean O'Neil Mar 02 '22 at 12:13
  • Never tried GetFileAttributes, it would be interesting to see if that's faster than the Windows.Storage way of doing it. – Sean O'Neil Mar 02 '22 at 12:14
0

I'm doing a Win10 IoT Core UWP app and I have to check the file length instead of "Exists" because CreateFileAsync() already creates an empty file stub immediately. But I need that call before to determine the whole path the file will be located at.

So it's:

    var destinationFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("MyFile.wow", ...);

    if (new FileInfo(destinationFile.Path).Length > 0)
        return destinationFile.Path;
Waescher
  • 5,361
  • 3
  • 34
  • 51
0

In this way System.IO.File.Exists(filePath) I cannot test DocumentLibrary because KnownFolders.DocumentsLibrary.Path return empty string

Next solution is very slow await DownloadsFolder.GetFileAsync("01-Introduction.pdf")

IMHO the best way is collect all files from folder and check the file name exist.

List<StorageFile> storageFileList = new List<StorageFile>();

storageFileList.AddRange(await KnownFolders.DocumentsLibrary.GetFilesAsync(CommonFileQuery.OrderByName));

bool fileExist = storageFileList.Any(x => x.Name == "01-Introduction.pdf");
Jarek
  • 307
  • 4
  • 12
0

CreateFileSync exposes an overload that let's you choose what to do if an existing file with the same name has been found in the directory, as such:

StorageFile localDbFile = await DownloadsFolder.CreateFileAsync(LocalDbName, CreationCollisionOption.OpenIfExists);

CreationCollisionOption is the object that you need to set up. In my example i'm opening the file instead of creating a new one.

Filipe Madureira
  • 420
  • 4
  • 17
0

Based on another answer here, I like

public static async Task<bool> DoesFileExist(string filePath) {
  var directoryPath = System.IO.Path.GetDirectoryName(filePath);
  var fileName = System.IO.Path.GetFileName(filePath);
  var folder = await StorageFolder.GetFolderFromPathAsync(directoryPath);
  var file = await folder.TryGetItemAsync(fileName);
  return file != null;
}
Tyson Williams
  • 1,630
  • 15
  • 35
-2

You can use the FileInfo class in this case. It has a method called FileInfo.Exists() which returns a bool result

https://msdn.microsoft.com/en-us/library/system.io.fileinfo.exists(v=vs.110).aspx

EDIT:

If you want to check for the files existence, you will need to create a StorageFile object and call one of the GetFile.... methods. Such as:

StorageFile file = new StorageFile();
file.GetFileFromPathAsync("Insert path")

if(file == null)
{
   /// File doesn't exist
}

I had a quick look to find the download folder path but no joy, but the GetFile method should give you the answer your looking for

Ben Steele
  • 414
  • 2
  • 10
  • 1
    Thanks Ben, both you and Absolute have hit in the right direction, but unfortunately I am currently only returning False, I have commented above with Absolute, how can I confirm which Directory/Folder is being searched for the FileInfo ? – James Tordoff May 10 '16 at 09:47
  • I think you may need to use the getfile functions to see if they return an object or null. Answer updated – Ben Steele May 10 '16 at 16:10
-2

On Window 10, for me, this is the most "elegant" way:

private static bool IsFileExistent(StorageFile file)
{
    return File.Exists(Path.Combine(file.Path));
}

Or, as an extension if you prefer and will use it widely:

static class Extensions
{
    public static bool Exists(this StorageFile file)
    {
        return File.Exists(Path.Combine(file.Path));
    }
}
  • This fails on files when paths are too long: https://stackoverflow.com/questions/11210408/file-exists-incorrectly-returns-false-when-path-is-too-long – visc Aug 10 '18 at 19:03
  • @visc on the Thread you an see on a comment that this method is expected to return false when any errors occurs when trying to reach file. So, if the system treats "path to long" as an error, this method is still right. The solution presented on the other thread is inefficient as the author confirms, I tried here to present the most "elegant" solution. And it works on 99.9% of times, so I don´t think its useful to integrate that solution on this proposal. – Wagner Bertolini Junior Aug 11 '18 at 15:22