2015-01-21 10 views
14

Próbuję znaleźć pliki z katalogu:Znajdź pliki za dziką kartę w 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(); 

Ale w search1, wybiera zarówno 85267-s.wav i 85267 -s.wav. Ale chcę tylko wybrać 85267-s.wav.

search2 ma się dobrze.

Jak mogę to zrobić?

+1

użyj ''? '', Jako symbolu wieloznacznego – Jodrell

+0

Czy możesz pokazać mi przykład? –

+3

@ adv12: czy to prawda? '*' Pojawia się po '-' nie wcześniej. –

Odpowiedz

7

Zachowanie, którego doświadczasz, jest spowodowane krótką nazwą pliku. Ponieważ dostaniesz 85267-~1.WAV dla 85267 -s.wav, a ponieważ pasuje do twojej dziczy karty "85267-*.wav", odzyskasz obydwa pliki.

wyjaśniono w Directory.GetFiles Method (String, String)

ponieważ metoda sprawdza przeciwko nazw plików z zarówno z 8,3 plików nazwa formatu i długa nazwa pliku formatu, wzorzec wyszukiwania podobnych do ". txt "może zwracać nieoczekiwane nazwy plików. Na przykład użycie wzorca wyszukiwania ". Txt" spowoduje zwrócenie "longfilename.txt", ponieważ format nazwy pliku 8.3 o nazwie 8.3 będzie miał wartość "longf ~ 1.txt".

Dla obejścia można użyć Directory.EnumerateFiles najpierw wybrać oba pliki pasujących do Twoich kryteriów, a następnie porównać część rzeczywista (długa) nazwa plik używając StartsWith. Pamiętaj, że EnumerateFiles robi leniwe oceny.

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

Tak, jest to efekt uboczny skrótu MS-Dos 8.3, który jest nadal włączony w większości systemów plików. Coś, co można zobaczyć za pomocą polecenia DIR/X, wyświetla te krótkie nazwy. Na mojej maszynie:

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 

Zwróć uwagę, że brakuje krótkiej nazwy dla "85267-s". To nie jest poprawna postać w krótkiej nazwie. To, co pozostało, pasuje również do twojego symbolu wieloznacznego.

To nie koniec problemów z tymi krótkimi nazwami. Symbol wieloznaczny, taki jak *.wav, będzie również pasował do pliku takiego, jak foobar.wavx, zupełnie innego typu pliku.

Generacja pokoleniowa to, szczerze mówiąc, relikt z poprzedniego wieku, który powinien zostać wyłączony dzisiaj. Ale to nie jest zazwyczaj coś, co możesz kontrolować. Musisz poradzić sobie z tymi przypadkowymi meczami i dokładnie sprawdzić, co otrzymasz. Na przykład z Regex.

+1

czy może framework powinien pozwolić ci wybrać typy plików, które chcesz przeszukać? – Jodrell

+0

Cóż, to nie jest sposób w jaki jest zaimplementowany. Framework właśnie przekazuje symbol wieloznaczny do systemu operacyjnego. Bardzo ważne, że działa w ten sposób, ponieważ sterownik systemu plików wykonuje filtrowanie znacznie szybciej. –

+0

cóż, jeśli sterownik systemu plików ... czekaj, widzę, dokąd to zmierza. Odnoszę się do twojej odpowiedzi. – Jodrell