В чем разница между File.Exists("") и FileInfo существует

У меня есть файл *.exe в \ProgramFiles (x86)\MyAppFolder.

В приложении x86 я проверяю, существует ли файл (64-разрядная система). простой:

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

Результат: "fileExists == false" (файл действительно есть). Это виртуализация, как я понимаю. Эта проблема описана здесь Ее хорошо. Но следующий код:

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

"fileExists == true"

Почему результат отличается от 1-го и 2-го случаев?

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);
}

//работает хорошо

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

//Не работает

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

Спасибо!

Ответ 1

Нет никакой разницы, эти методы используют точно такой же внутренний вспомогательный метод внутри .NET Framework. Что-то, что вы можете увидеть с помощью декомпилятора или исходного кода ссылки, вспомогательный метод называется File.FillAttributeInfo().

Подобное дублирование в .NET Framework довольно необычно, и это не совсем хорошо, когда есть несколько способов выполнить одно и то же. Класс File, однако, особенный, он был добавлен после исследования юзабилити, проведенного при поставке .NET 1.0. Испытуемые имели только базовые классы BCL для работы, такие как FileStream и FileInfo, а в остальном были доступны только документы MSDN. Результаты теста были не очень хорошими, класс File был добавлен, чтобы помочь программистам попасть в пропасть успеха при написании очень простого кода для манипулирования файлами. Как File.Exists() и File.ReadAllLines().

Так что это не имеет ничего общего с классами, вы просто неправильно их используете. Как на самом деле не использовать тот же путь. Обращайтесь с прямыми слешами проще, сопоставление с обратными слешами происходит внутри Windows и непоследовательно реализуется в другом коде. Использование//определенно не делает то, на что вы надеетесь.

Ответ 2

Это единственное различие, и оно больше связано с природой 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

Итак, вы можете увидеть, что значение fileInfo.Exists кэшируется при первом использовании.

Кроме того, они делают то же самое за кулисами.

Ответ 3

в вашем первом случае, путь к файлу неверен, вам нужны пробелы в "Program Files (x86)".

Во-вторых, Path.Combine вернет путь к каталогу, так что вы получите что-то вроде "C:\Program Files (x86)\MyAppFolder\Manager.exe\" так что это плохая идея.

Оба метода работают одинаково, поэтому убедитесь, что вы правильно указали путь.

Ответ 4

Разница между File.Exists() и new FileInfo().Exists в этом поведении при полном пути (имя каталога + имя файла) длинна: ​​

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;

Ответ 5

Я воспроизвел ваш сценарий, используя ниже 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();

Отказалось от этого, когда файл существовал, а когда он этого не делал, и оба производили один и тот же вывод каждый раз.  Возможно, попробуйте это в своей системе и посмотрите, все ли видите различия.