48
System.IO.File.Exists(string path)

returns always false, even when the file exists on the specified path. What could be the possible solution?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shilpa Soni
  • 2,034
  • 4
  • 27
  • 38
  • 6
    *If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path.* – V4Vendetta Aug 16 '13 at 05:53
  • 2
    May be its about insufficient privilges? Try to run exe as administrator. – Farhad Jabiyev Aug 16 '13 at 05:53

15 Answers15

58

It could well be a permission problem. From the documentation:

The Exists method returns false if any error occurs while trying to determine if the specified file exists. This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, a failing or missing disk, or if the caller does not have permission to read the file.

One way of seeing what's happening is to just try to read the file (e.g. with File.OpenRead). I'd be surprised if that succeeds - but if it fails, the exception should give you more information.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 21
    File.OpenRead worked for me. but File.Exists still returns false.. i'm baffled... – Vlad Jul 15 '15 at 14:00
  • 2
    @Vlad Yep, same here. I was using an impersonation context - I don't know if that had anything to do with it. But if it can read it -- I even created a `Stream s = File.OpenRead(path);` and used a function to read in the bytes to a byte array! -- I don't know why it can't return `true` for `bool fileExists = File.Exists(path);`; Actually, it's possible the "too many characters" in the file path might've been what it was, for me. – vapcguy Oct 17 '17 at 19:59
  • 1
    Note: In case you are looking in `System32`, and actualy want `System32` instead of `SysWOW64`, you are looking for `Sysnative`. Long Story Short: Use `%windir%\Sysnative` instead of `%windir%\system32`. – Christian Gollhardt Oct 25 '21 at 20:20
  • 1
    I wonder if microsoft defender could cause this... or any AV... – CamHart Nov 11 '22 at 15:44
17

Hiding file endings in windows can sometimes cause confusion: you KNOW your file is named file.txt when it is actually named file.txt.txt because the last 4 characters have been hidden by the OS.

bugmagnet
  • 191
  • 1
  • 5
17

One possibility not mentioned in any of the answers here is 'File System Redirection' on Windows 8.1 onward.

For example, if your program is a 32-bit application and you're running on 64-bit Windows then an attempt to access %windir%\System32 would be redirected to %windir%\SysWOW64. And if the file you're trying to access doesn't exist in %windir%\SysWOW64 then System.IO.File.Exists(string path) would return False.

Link to a nice article explaining this behavior

NGambit
  • 1,141
  • 13
  • 27
  • 3
    Thank you SO MUCH!!!!!!!!!!! I was stuck on this for like, I don't know, at least four hours. – melanie johnson Jan 04 '18 at 19:43
  • 1
    I cannot belive this. I was doing File.Exists("C:\\WINDOWS\\system32\\bash.exe") it was returing false, when I copied the file to C:\Windows\SysWOW64 it started working. I was not expecting this at all. Thank you NGambit. Learning something new today. – CBBSpike Dec 03 '18 at 15:13
  • 2
    Thank you very much for the hint. On 32bit-app on 64bit-CPU, `%windir%\Sysnative` is redirected to `%windir%\System32`. On 64bit-app or 32bit-app on 32bit-CPU, `%windir%\Sysnative` is not existed. see also: https://learn.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector – okud Feb 05 '20 at 13:33
  • 1
    I just had to uncheck "Prefer 32-bit" on "Build" of the project Properties and it magically started working! I'm amazed that a .NET 4.8 Visual Studio 2019 Console application is still set to favour 32-bit by default! – Sphynx Jul 27 '20 at 21:10
8

I was puzzling over this as well, then realized I was using File.Exists when I should have been using Directory.Exists.

D. Haskins
  • 101
  • 1
  • 5
7

How I got around this was using Server.MapPath(fileName) as it kept trying to find the file somewhere else.

System.IO.File.Exists(Server.MapPath(string path))
Oleg
  • 24,465
  • 8
  • 61
  • 91
F U
  • 91
  • 1
  • 8
  • 2
    Does anyone know if this is a difference between .NET versions or something? This used to work before an app was upgraded to .NET 4.5. Now all of a sudden, it's an issue. – Will Strohl Sep 15 '16 at 05:43
  • 1
    This won't work in Windows applications, unfortunately – MC9000 Nov 29 '17 at 01:35
  • 2
    I think in the web project this issue must be checked as a first factor. – QMaster Jan 01 '19 at 12:29
7

in my case, a different "dash" in file name causes the issue.

var f1 = "4-37R.pdf";
var f2 = "4‐37R.pdf";
var r = f1==f2?"same":"diff";
Console.Write(r); //diff

turns out

var c1 = '-';
var c2 = '‐';
Console.WriteLine((int)c1); //45
Console.WriteLine((int)c2); //8208

use the same '-' fixes the issue.

Rm558
  • 4,621
  • 3
  • 38
  • 43
  • 2
    My jaw is still on the ground after seeing this to be true in my case as well. Who would have thought? – Lukas Aug 14 '19 at 18:28
  • 1
    In my case there were a few non-printable unicode characters from the string I was reading in from a file. After much head scratching I discovered they came from a BOM – Matt Thomas Sep 20 '19 at 18:14
3

This had me stumped for a while while I was debugging a service locally, I was running File.Exists("U:\dir1") against a server location mapped on my workstation as (U:). I replaced the U:\dir1 to "\\serverPath\dir1" and File.Exists then returned true.

Ionselat
  • 71
  • 4
2

I was experiencing this myself too. In my case, I was deleting the file and re-creating it. In the process that was deleting the file, I forgot to add in WaitForExit() before using File.Exists later on

Tasos K.
  • 7,979
  • 7
  • 39
  • 63
Krondorian
  • 616
  • 1
  • 9
  • 21
2

I just learned today that System.IO.File.Exists will return false if the file exists but is empty

Rob
  • 3,488
  • 3
  • 32
  • 27
1

System.IO.File.Exists(string path) returned false for me while trying to read C:\OpenSSL\bin\file.txt. Running the application in Administrator mode did not help. (I was logged on the administrator account, Windows 10) Once I moved the file to C:\Users\MyUser\Desktop\file.txt, File.Exists() returned true.

Tammar
  • 11
  • 1
  • 3
1

Here's one more, which took me far too long to twig to.

The file name was in a constructed variable that was use to write the file, then the same variable used to check that it had been successfully written, so it could not have been different versions of '-'. I am running mono on Linux and debugging as a different user than the program is normally run by/as. Many of these types of errors are related to permissions and I spent a while banging my head on that. When File.OpenRead also threw "file not found" I finally noticed my file name had a space character at the end. I only saw this when I copied the exception message, which showed quote marks around the file name string, revealing the included space.

Apparently you can write a file name with a trailing space, but File.Exists trims that off and doesn't recognize it. When I eliminated the trailing space File.Exists worked as expected.

1

There can be requirement to use the DirectoryProvider Refresh() process to get the correct result from the Exists function.

e.g. code as per:

    private DirectoryInfo CreateDirectory(string folderPath, int code, string message)
    {
        DirectoryInfo di;
        try
        {
            di = DirectoryProvider.CreateDirectory(folderPath);
        }
        catch
        {
            throw new WebServiceException(code, HttpStatusCode.BadRequest, message);
        }

        di.Refresh();

        if (!DirectoryProvider.Exists(di))
        {
            throw new WebServiceException(code, HttpStatusCode.BadRequest, message);
        }

        return di;
    }
Allan F
  • 2,110
  • 1
  • 24
  • 29
1

I was using System.IO.Path.Combine and assuming it would remove any trailing white space. For the life of me I could figure out why System.IO.File.Exists(path) was returning false.

I used the below snippet to test why it was failing

Turns out that a trailing white space was introduced causing an "The filename, directory name, or volume label syntax is incorrect inside batch"

Hopefully someone will avoid the same stupid mistake as me

bool FileExists(string path){

    try
    {
        using var stream = File.Open(path, FileMode.Open);
        return true;
    }
    catch (FileNotFoundException)
    {
        return false;
    }
    catch (DirectoryNotFoundException)
    {
        return false;
    }
    catch (UnauthorizedAccessException ex)
    {
        Console.WriteLine(ex.message);
        throw;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.message);
        throw;
    }

}
BDarley
  • 697
  • 1
  • 10
  • 19
1

I had to use the absolute path even though the file clearly existed in the current working directory.

For example this worked:

[System.IO.File]::Exists((Resolve-Path '.\file.json'))

while this did not:

[System.IO.File]::Exists('.\file.json')

which was baffling to me.

Zitrax
  • 19,036
  • 20
  • 88
  • 110
1

There is way to make function File.Exists to return correct value in 32-bit program. Before calling File.Exists one must call function Wow64DisableWow64FsRedirection. After manipulation with File.Exists one must call Wow64RevertWow64FsRedirection to enable redirection again. Here is example:

using System.IO;
using System.Runtime.InteropServices;

namespace example
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll", EntryPoint = "Wow64DisableWow64FsRedirection")]
        public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
        [DllImport("kernel32.dll", EntryPoint = "Wow64RevertWow64FsRedirection")]
        public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string fn = @"C:\Windows\System32\wsqmcons.exe";
            IntPtr ptr = new IntPtr();
            Wow64DisableWow64FsRedirection(ref ptr);
            button1.Text = File.Exists(fn).ToString();
            Wow64RevertWow64FsRedirection(ptr);
        }
    }
}
Zagavarr
  • 191
  • 1
  • 9