15

I have an *.exe file in \ProgramFiles(x86)\MyAppFolder.

In x86 application I check if the file exists (64 bit system). simple:

bool fileExists = File.Exists(@"\ProgramFiles(x86)\MyAppFolder\Manager.exe");

The result is: "fileExists == false" (the file is really there). It's Virtualization as I understand.That issue described here Its ok. But next code:

bool fileExists = new FileInfo("\\Path").Exists;

"fileExists == true"

Why is the result different in 1st and 2nd cases?

var controller = new ServiceController(Product.ServiceName);
_manager.Enabled = controller.Status == ServiceControllerStatus.Running;

var info = new DirectoryInfo(Assembly.GetExecutingAssembly().Location);

var s = File.Exists(@"D:\TFS\GL_SOURCES\Teklynx_LPM\Dev\Server\Debug\Manager.exe");

string pathToManager = string.Empty;

if (info.Parent != null)
{
    var pathToModule = info.Parent.FullName;
    pathToManager = Path.Combine(pathToModule,"Manager.exe").Replace(" ",string.Empty);
}

//works good

var fileInfo = new FileInfo(pathToManager);
var managerSeparator = new ToolStripSeparator()
{
    Visible = _manager.Visible = fileInfo.Exists // true
};

//Does not work

var managerSeparator = new ToolStripSeparator()
{
    Visible = _manager.Visible = File.Exists(pathToManager ) // false
};

Thanks!

Community
  • 1
  • 1
Baranovskiy Dmitry
  • 463
  • 2
  • 5
  • 23
  • 1
    For windows, file system paths use `\\ and not `/, and... your example calls use different paths...? – crashmstr Feb 26 '14 at 13:08
  • 4
    I can imagine that the only reason to use FileInfo.Exist over File.Exists is if you are going to use the FileInfo object later on. – Richard Priddy Feb 26 '14 at 13:09
  • 2
    Are you using "ProgramFiles(x86)" as described? because this folder name contains spaces "Program Files (x86)" – cichy Feb 26 '14 at 13:09
  • 2
    oh, its mine mistake. I have used the Assembly.GetExecutingAssembly().Location and then combined the path like (Path.Combine(pathToModule,"Manager.exe")). so the slashes shoul be correct. – Baranovskiy Dmitry Feb 26 '14 at 13:11
  • 1
    @crashmstr: You can use either slash on Windows file systems. – Jon Skeet Feb 26 '14 at 13:11
  • 2
    Have you tried: bool fileExists = File.Exists(@"C:\Program Files (x86)\MyAppFolder\Manager.exe"); ? – Richard Priddy Feb 26 '14 at 13:11
  • sure that is not a problem of relative path? check the path where the File.Exist() check for the file. – abrfra Feb 26 '14 at 13:10

6 Answers6

33

This is about the only difference and it has more to do with the nature of FileInfo:

FileInfo fileInfo = new FileInfo("myFile.txt"); // non-existent file
Console.WriteLine(fileInfo.Exists);             // false
File.Create("myFile.txt");
Console.WriteLine(File.Exists("myFile.txt"));   // true
Console.WriteLine(fileInfo.Exists);             // false

So as you can see the value of fileInfo.Exists is cached the first time you use it.

Other than that, they do the same thing behind the scenes.

David Sherret
  • 101,669
  • 28
  • 188
  • 178
  • 10
    This is actually a critical difference in behavior! On the face of things, I'm pretty sure most people would expect that to fail or succeed based on the current status of the file, not on some cached status of that file. – ouflak May 24 '16 at 16:04
  • @ouflak yeah, [that definitely happens](http://stackoverflow.com/q/17839745/188246) – David Sherret May 26 '16 at 14:20
17

There is no difference, these methods use the exact same internal helper method inside the .NET Framework. Something you can see with a decompiler or the Reference Source source code, the helper method name is File.FillAttributeInfo().

Having duplication like this in the .NET Framework is pretty unusual, not exactly a Good Thing to have more than one way to accomplish the same thing. The File class is however special, it got added after a usability study conducted when .NET 1.0 shipped. The test subjects just had the basic BCL classes to work with, like FileStream and FileInfo, and otherwise only had MSDN documentation available. The test results were not very good, the File class got added to help programmers fall in the pit of success writing very basic file manipulation code. Like File.Exists() and File.ReadAllLines().

So it doesn't have anything to do with the classes, you are just using them wrong. Like not actually using the same path. Do go easy on the forward slashes, the mapping to backward slashes happens inside Windows and is inconsistently implemented in other code. Using // certainly doesn't do what you hope it does.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Looks like i am going crazy, but now I cant reproduce the issue after VS restarting(same code). The issue has been found as a bug on our software, and has a really strage way for reproducing, actually, when you start app first time everything is fine, but "File is not found!" after OS rebooting. I can stably reproduce this on a software. Anyway, I am agreed - File.Exists() and .Exist prop. are the same things and the problem somewhere else. Thanks! – Baranovskiy Dmitry Feb 26 '14 at 13:59
  • Note: Per https://stackoverflow.com/a/22046285/361842 there is a difference... i.e. `File.Exists(myFilePath)` is invoked when you call it, so checks the current state; `myFileInfo.Exists` is invoked the first time it's called; then the same value is returned for each subsequent call, even if the underlying filesystem's state has changed (i.e. the file has been created or deleted). – JohnLBevan Nov 05 '21 at 10:33
2

I just found this thread and wanted to update it as I had an issue with FileInfo vs File.Exists.

Let's take a scenario where we create a fileinfo object for a file that currently doesn't exist on a UNC share.

bool fileInfo  = new FileInfo(@"\\uncshare\name\filename.txt");

At this point, the file does not exist, but if I create it using another tool (other code or outside my app) and then do this...

fileInfo.Refresh();
bool exists = fileInfo.Exists;

The result is false, it does not exist, even though it does and the fileInfo was refreshed.

To get the correct result requires..

bool exists = File.Exists(f);

Hope that helps others.

1

I've replicated your scenario using the below Linqpad script

var f = @"C:\Program Files (x86)\MyAppFolder\manager.exe";

bool fileExists = File.Exists(f);
bool fileInfoExists = new FileInfo(f).Exists;

fileExists.Dump();
fileInfoExists.Dump();

Ran this both when the file existed and when it did not and both produced the same output each time. Maybe try this on your system and see if you still see differences.

hermiod
  • 1,158
  • 4
  • 16
  • 27
1

in your first case, the file path is incorrect, you need spaces in "Program Files (x86)".

Secondly, the Path.Combine will return a Directory path so you'll end up with something like "C:\Program Files (x86)\MyAppFolder\Manager.exe\" so it's a bad idea.

Both methods work the same way, so make sure you check that the path is correct.

Sebastien H.
  • 6,818
  • 2
  • 28
  • 36
  • 2
    I have never seen the problem you describe in your "Secondly" paragraph. Can you show an example where you do not explicitly have a "\" at the end of the final Path.Combine parameter? – Andrew Morton Oct 06 '16 at 19:01
1

The difference between File.Exists() and new FileInfo().Exists on it's behavior when full path (directory name + file name) is long:

var f = @"C:\Program Files (x86)\MyAppFolder\many_subfolders\manager.exe";

//f.length > 260 characters

bool fileExists = File.Exists(f); //return false, even if the file exists

// Throw exception: "The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters."
bool fileInfoExists = new FileInfo(f).Exists;
Iguana
  • 11
  • 1