2012-11-09 12 views
41

C'è un modo per semplificare questa espressione di linq o esiste un modo migliore per farlo?Directory.GetFiles di determinati interni

Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories) 
     .Where(s => s.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || 
        s.EndsWith(".gif", StringComparison.OrdinalIgnoreCase) || 
        s.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || 
        ...); 

In sostanza, voglio restituire tutti i file di una determinata estensione. Sfortunatamente, questo metodo non è molto flessibile. Preferirei essere in grado di aggiungere estensioni a un elenco e fare in modo che Directory.GetFiles restituisca tali estensioni. È possibile?

+1

Duplicate: http://stackoverflow.com/questions/163162/can-you-call-directory-getfiles-with-multiple-filters –

risposta

68

Se volete fare il vostro filtraggio in LINQ , si può fare in questo modo:

var ext = new List<string> {"jpg", "gif", "png"}; 
var myFiles = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories) 
    .Where(s => ext.Contains(Path.GetExtension(s))); 

Ora ext contiene un elenco di estensioni consentiti; puoi aggiungere o rimuovere elementi secondo necessità per un filtro flessibile.

+0

Posso eseguire test, ma sai quale sarebbe più efficiente? – XSL

+0

Interessante che funzioni ... Dalla documentazione su 'GetFiles', non sembra che accetti il' | 'come ci si aspetterebbe da un'espressione regolare. I documenti dicono che riconosce solo '* e'? ', Ma hey, se funziona, funziona =) –

+0

Nota: Questo non sembra funzionare su Win7 x64 con .NET 4.5. Lancia 'Caratteri non ammessi nel percorso' a causa della pipe. –

10

Il sovraccarico di Directory.GetFiles(String, String) non lo fa già? Dovresti solo fare Directory.GetFiles(dir, "*.jpg", SearchOption.AllDirectories)

Se vuoi metterli in una lista, allora basta sostituire lo "*.jpg" con una variabile che scorre su un elenco e aggregare i risultati in un insieme di risultati complessivo. Molto più chiaro rispetto a specificarli individualmente. =)

Qualcosa di simile ...

foreach(String fileExtension in extensionList){ 
    foreach(String file in Directory.GetFiles(dir, fileExtension, SearchOption.AllDirectories)){ 
     allFiles.Add(file); 
    } 
} 

(Se le directory sono di grandi dimensioni, utilizzando EnumerateFiles invece di GetFiles può potenzialmente essere più efficiente)

+0

Grazie . Mi piace l'idea, ma non sono sicuro di quanto sarebbe efficiente chiamare GetFiles molte volte in un ciclo. – XSL

+0

Vedere il commento aggiuntivo sul metodo EnumerateFiles. –

+0

Grazie per il suggerimento, ma sembra che EnumerateFiles sia disponibile solo per .net 4 ma devo usare 3.5. Colpa mia, per non averlo detto prima, scusa. – XSL

4

avrei fatto utilizzando solo la linea singola come

List<string> imageFiles = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories) 
     .Where(file => new string[] { ".jpg", ".gif", ".png" } 
     .Contains(Path.GetExtension(file))) 
     .ToList();