2013-11-27 11 views
10

Używam następujący wiersz, aby powrócić konkretnych plików ...GetFiles() - wyszukiwanie wzorca

FileInfo file in nodeDirInfo.GetFiles("*.sbs", option) 

Ale istnieją inne pliki w katalogu z rozszerzeniem „.sbsar”, a to jest ich coraz także. Jak mogę rozróżnić ".sbs" i ".sbsar" we wzorcu wyszukiwania?

+1

Nie można (przynajmniej z GetFiles/GetDirectories). Jest to "ograniczenie" wzorca wyszukiwania. Powinieneś iterować wyniki i filtrować ręcznie te, które chcesz. – varocarbas

+0

również przyjrzyj się temu: http://msdn.microsoft.com/en-us/library/wz42302f(v=vs.110).aspx –

+0

możliwy duplikat [Exact file extension match with GetFiles()?] (http://stackoverflow.com/questions/5573063/exact-file-extension-match-with-getfiles) – Borja

Odpowiedz

4

Spróbuj tego, przefiltrowanego przy użyciu rozszerzenia pliku.

FileInfo[] files = nodeDirInfo.GetFiles("*", SearchOption.TopDirectoryOnly). 
      Where(f=>f.Extension==".sbs").ToArray<FileInfo>(); 
3

To zachowanie Win32 API (FindFirstFile), które znajduje się pod Tobą pod GetFiles().

Musisz wykonać własne filtrowanie, jeśli musisz użyć GetFiles(). Na przykład:

GetFiles("*", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 

lub skuteczniejszego:

EnumerateFiles("*", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 

Należy pamiętać, że używam StringComparison.InvariantCultureIgnoreCase do czynienia z faktem, że nazwy plików Windows są wielkości liter.

Jeśli wydajność jest problemem, to znaczy jeśli wyszukiwanie ma przetwarzać katalogi z dużą liczbą plików, wówczas wydajniejsze jest dwukrotne wykonanie filtrowania: jeden raz w rozmowie z numerem GetFiles lub EnumerateFiles, a jeden raz w celu wyczyszczenia niechciane nazwy plików. Na przykład:

GetFiles("*.sbs", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 
EnumerateFiles("*.sbs", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 
+0

@Joey To po prostu wydaje mi się trochę brudne, duplikuje filtr. Ale może miałoby to implikację perf.Jeśli nie, wolę mieć tylko jeden filtr. –

+0

Jest to jednak szybsze ;-) W moim małym teście (przeszukiwanie naszego kompletnego folderu źródłowego, wyszukiwanie '* .cpp') jest o 10-25% szybsze określenie filtru również w' GetFiles'. 'EnumerateFiles' jest nieco wolniejszy, ale prawdopodobnie zużywa znacznie mniej pamięci, szczególnie w przypadku dużych zestawów wyników. – Joey

+0

@Joey Tak, myślę, że to rozsądne. Sądzę, że sprowadza się to do równowagi pomiędzy perfekcją a czystością! Omówiłem to teraz w odpowiedzi. –

9

Kwestia jesteś przeżywa to limitation wzorca wyszukiwania, w Win32 API.

searchPattern z rozszerzeniem pliku (na przykład * .txt) w dokładnie trzech znaków zwraca pliki posiadające rozszerzenie trzech lub więcej znaków, gdzie pierwsze trzy znaki pasują do rozszerzenia pliku określonej w searchPattern .

Moje rozwiązanie jest do ręcznego filtrowania wyników, przy użyciu LINQ:

nodeDirInfo.GetFiles("*.sbs", option).Where(s => s.EndsWith(".sbs"), 
    StringComparison.InvariantCultureIgnoreCase)); 
+2

Nie rozliczasz się z tego przypadku. –

+0

To prawda, naprawione. –

0

Jej wymienionych w docs

Podczas używania znaku gwiazdka wieloznaczny w searchPattern, A searchPattern z rozszerzenie dokładnie trzech znaków zwraca pliki z rozszerzeniem trzech lub więcej znaków. Gdy używa znaku zapytania dzikiego znak karty, ta metoda zwraca tylko pliki pasujące do określonego rozszerzenia pliku.

+0

Byłoby cudownie, gdyby to była prawda. Niestety, to nie jest i oto nadchodzi nowy odcinek złych opisów searchPattern w MSDN :) Czułem się ciekawy i zrobiłem kilka testów i tu dochodzę do moich wniosków ... – varocarbas

+0

@varocarbas rzeczywiście..Wonder gdzie użyć '?' .OP może używać '* a? .sbs' .. Chociaż wymagałoby to, aby' a' znajdowało się gdzieś w nazwie pliku – Anirudha

+2

'nodeDirInfo.GetFiles (" 5? .txt ");' zwraca dowolny plik z właśnie .txt (nie .txtwhatever) zawierające dwa znaki w nazwie, z których jeden to 5. 'nodeDirInfo.GetFiles ("? .txt ");' Zwraca dowolny plik .txt z tylko jednym znakiem w nazwie (nie wliczając .txtwhatever). Możesz uzyskać tylko * .txt używając "????. Txt", jeśli znasz maksymalną długość szukanych nazw plików (??. Txt retunuje wszystkie pliki z 1 lub 2 znakami w nazwie ; ???. txt wszystkie z 1,2 i 3 itd.). – varocarbas