2014-02-26 6 views
9

Ich habe eine * .exe-Datei in \ ProgramFiles (x86) \ MyAppFolder.Was ist der Unterschied zwischen File.Exists ("") und FileInfo existiert

In x86-Anwendung überprüfe ich, ob die Datei existiert (64-Bit-System). einfach:

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

Das Ergebnis ist: "fileExists == false" (die Datei wirklich da ist). Es ist Virtualisierung, wie ich verstehe. Dieses Problem beschrieben here Es ist in Ordnung. Aber nächste Code:

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

"fileExists == true"

Warum ist das Ergebnis anders in der 1. und 2. Fälle?

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

// funktioniert gut

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

// nicht

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

Dank Funktioniert!

+1

Für Fenster, Dateisystempfade verwenden '\\ und nicht'/und .. Ihre Beispielanrufe verwenden unterschiedliche Pfade ...? – crashmstr

+4

Ich kann mir vorstellen, dass der einzige Grund, FileInfo.Exist über File.Exists zu verwenden, ist, wenn Sie später das FileInfo-Objekt verwenden. –

+2

Verwenden Sie "ProgramFiles (x86)" wie beschrieben? weil dieser Ordnername Leerzeichen enthält "Programme (x86)" – cichy

Antwort

13

Es gibt keinen Unterschied, diese Methoden verwenden genau die gleiche interne Hilfsmethode in .NET Framework. Etwas, das Sie mit einem Decompiler oder dem Quellcode der Referenzquelle sehen können, ist der Name der Hilfsmethode File.FillAttributeInfo().

Verdopplung wie diese in .NET Framework ist ziemlich ungewöhnlich, nicht gerade eine gute Sache, mehr als eine Möglichkeit, das gleiche zu erreichen. Die File-Klasse ist jedoch besonders, sie wurde nach einer Usability-Studie hinzugefügt, die vor der Auslieferung von .NET 1.0 durchgeführt wurde. Die Testpersonen hatten nur die grundlegenden BCL-Klassen wie FileStream und FileInfo und ansonsten nur die MSDN-Dokumentation. Die Testergebnisse waren nicht sehr gut, die File-Klasse wurde hinzugefügt, um Programmierern zu helfen, in die Grube des Erfolgs zu fallen und sehr einfachen Dateimanipulationscode zu schreiben. Wie File.Exists() und File.ReadAllLines().

Also hat es nichts mit den Klassen zu tun, Sie verwenden sie nur falsch. Als ob man nicht den gleichen Pfad benutzt. Gehen Sie bei den Schrägstrichen vorsichtig vor, die Zuordnung zu umgekehrten Schrägstrichen erfolgt in Windows und ist in anderem Code inkonsistent implementiert. Die Verwendung von // macht sicherlich nicht das, was Sie hoffen.

+0

Sieht so aus, als ob ich verrückt werde, aber jetzt kann ich das Problem nicht reproduzieren, nachdem VS neu gestartet wurde (gleicher Code). Das Problem wurde als ein Fehler in unserer Software gefunden, und hat eine wirklich stabile Möglichkeit zur Wiedergabe. Wenn Sie die App zum ersten Mal starten, ist alles in Ordnung, aber "Datei wird nicht gefunden!" nach dem Neustart des Betriebssystems. Ich kann das auf einer Software stabil reproduzieren. Wie auch immer, ich bin einverstanden - File.Exists() und .Exist prop. sind die gleichen Dinge und das Problem woanders. Vielen Dank! –

0

ich Ihr Szenario mit dem unten Linqpad Skript

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

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

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

diese beiden Ran repliziert haben, wenn die Datei existiert und wenn es nicht der Fall war und beide erzeugt die gleiche Ausgabe jedes Mal. Vielleicht versuchen Sie dies auf Ihrem System und sehen Sie, ob Sie immer noch Unterschiede sehen.

1

In Ihrem ersten Fall ist der Dateipfad falsch, Sie benötigen Leerzeichen in "Program Files (x86)".

Zweitens wird die Path.Combine einen Verzeichnispfad zurückgeben, so dass Sie mit etwas wie "C:\Program Files (x86)\MyAppFolder\Manager.exe\" enden werden, so ist es eine schlechte Idee.

Beide Methoden funktionieren auf die gleiche Weise. Stellen Sie daher sicher, dass der Pfad korrekt ist.

+1

Ich habe das Problem, das Sie beschreiben, nie in Ihrem "zweiten" Absatz gesehen. Können Sie ein Beispiel zeigen, bei dem Sie am Ende des endgültigen Path.Combine-Parameters nicht explizit ein "\" haben? –

16

Das ist so ziemlich der einzige Unterschied, und es hat mehr mit der Natur der FileInfo zu tun:

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 wie Sie den Wert von fileInfo.Exists sehen das erste Mal zwischengespeichert wird Sie es verwenden.

Ansonsten tun sie das gleiche hinter den Kulissen.

+2

Dies ist tatsächlich ein kritischer Unterschied im Verhalten! Auf den ersten Blick bin ich mir ziemlich sicher, dass die meisten Leute erwarten würden, dass das Scheitern oder der Erfolg auf der Grundlage des aktuellen Status der Datei und nicht auf dem zwischengespeicherten Status dieser Datei beruht. – ouflak

+0

@oaltak ja, [das passiert definitiv] (http://stackoverflow.com/q/17839745/188246) –

0

Der Unterschied zwischen File.Exists() und new FileInfo().Exists darauf Verhalten ist, wenn vollständiger Pfad (Verzeichnisname + Dateiname) lang ist:

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;