2015-01-21 15 views
14

ich Dateien aus einem Verzeichnis zu finden versuchen:Suche Dateien Wild Card in C#

String[] search1 = Directory.GetFiles(voiceSource, "85267-*.wav") 
           .Select(path => Path.GetFileName(path)) 
           .ToArray(); 

String[] search2 = Directory.GetFiles(voiceSource, "85267 *.wav") 
           .Select(path => Path.GetFileName(path)) 
           .ToArray(); 

Aber in search1, wählt er sowohl 85267-s.wav und 85267 -s.wav. Aber ich möchte nur 85267-s.wav ausgewählt werden.

search2 geht es gut.

Wie kann ich das tun?

+1

Verwenden Sie ein ''? '', Als die Wildcard – Jodrell

+0

Können Sie mir bitte ein Beispiel zeigen? –

+3

@ adv12: ist es? Das '*' kommt nach dem '-' nicht vorher. –

Antwort

7

Das Verhalten, das Sie feststellen, liegt an einem kurzen Dateinamen. Da du 85267-~1.WAV für 85267 -s.wav bekommst und da das deiner Wildcard "85267-*.wav" entspricht, bekommst du beide Dateien zurück.

Das erklärt in Directory.GetFiles Method (String, String)

Da diese Methode überprüft, gegen Dateinamen sowohl mit dem 8.3-Datei Namensformat und das langen Dateinamenformat, ein Suchmuster ähnlich auf ". txt "kann unerwartete Dateinamen zurückgeben. Wenn Sie beispielsweise ein Suchmuster von " .txt" verwenden, wird "longfilename.txt" zurückgegeben, da das entsprechende 8.3-Dateinamensformat "longf ~ 1.txt" lautet.

Für Abhilfe können Sie Directory.EnumerateFiles verwenden, um zuerst die beiden Dateien wählen Sie Ihre Suchkriterien entsprechen und vergleichen dann die tatsächlichen (long) Teil Dateinamen StartsWith. Denken Sie daran, EnumerateFiles macht faule Bewertung.

String[] search1 = Directory.EnumerateFiles(@"C:\test", "85267-*.wav") 
         .Where(file => Path.GetFileName(file).StartsWith("85267-")) 
         .Select(path => Path.GetFileName(path)) 
         .ToArray(); 
8

Ja, dies ist ein Nebeneffekt der Kurznamenunterstützung von MS-Dos 8.3, die auf den meisten Dateisystemen noch heute aktiviert ist. Etwas, das Sie mit dem Befehl DIR/X sehen können, zeigt diese kurzen Namen an. An meinem Gerät:

C:\temp>dir /x *.wav 

01/21/2015 09:11 AM     6 85267-~1.WAV 85267 -s.wav 
01/21/2015 09:11 AM     6    85267-s.wav 
       2 File(s)    12 bytes 
       0 Dir(s) 235,121,160,192 bytes free 

Beachten Sie, wie der kurze Name für "85267 -s" den Raum fehlt. Es ist kein gültiges Zeichen in einem kurzen Namen. Was übrig bleibt, entspricht nun auch deiner Wildcard.

Das ist nicht, wo das Problem mit diesen kurzen Namen endet. Ein Platzhalter wie *.wav entspricht auch einer Datei wie foobar.wavx, einem völlig anderen Dateityp.

Kurznamengeneration ist, offen gesagt, ein Relikt aus dem vorigen Jahrhundert, das heute abgeschaltet werden sollte. Aber das ist normalerweise nichts, was Sie selbst kontrollieren können. Sie müssen mit diesen zufälligen Übereinstimmungen umgehen und überprüfen, was Sie zurückbekommen. Zum Beispiel mit einem Regex.

+1

oder vielleicht das Framework sollte Sie wählen, welche Arten von Dateinamen Sie suchen möchten? – Jodrell

+0

Nun, so ist es nicht implementiert. Das Framework übergibt den Platzhalter nur an das Betriebssystem. Ziemlich wichtig, dass es so funktioniert, mit dem Dateisystemtreiber ist die Filterung viel schneller. –

+0

gut, wenn der Dateisystemtreiber ... warte, kann ich sehen, wohin das führt. Ich beziehe mich auf deine Antwort. – Jodrell