2010-09-22 5 views

Respuesta

17

No es necesario utilizar LINQ para hacer esto - es built into the framework:

string[] files = Directory.GetFiles(directory, "*.dll", 
            SearchOption.AllDirectories); 

o if you're using .NET 4:

IEnumerable<string> files = Directory.EnumerateFiles(directory, "*.dll", 
                SearchOption.AllDirectories); 

Para ser sinceros, LINQ no es grande en términos de la recursividad. Probablemente quieras escribir tu propio método de extensión recursivo de propósito general. Teniendo en cuenta la frecuencia se hace esta clase de pregunta, que realmente debería hacer que yo algún tiempo ...

+0

gracias ... que incluye la ruta de acceso total. Solo necesito el nombre del archivo como 'foo.dll ' –

+4

@Pramodh: así que use' Path.GetFileName' también. –

+1

Vale la pena señalar que estos métodos tienen graves fallas, sin embargo, si se produce alguna excepción de E/S, se cancela todo el resultado. En la variante GetFiles, esto significa que generalmente no arroja ningún resultado, y en la variante EnumerateFiles, la enumeración se detendrá cada vez que se produzca el primer error de E/S (como el permiso denegado). –

2
IEnumerable<string> filenames = Directory.GetFiles(searchDirectory, "*.dll", 
                SearchOption.AllDirectories) 
             .Select(s => Path.GetFileName(s)); 

Directory.GetFiles() devuelve la ruta completa de los archivos que coinciden con el patrón de búsqueda especificado en el directorio especificado. Select proyecta cada elemento de la secuencia de ruta completa en una nueva forma, solo el nombre de archivo.

0

La lectura de archivos y directorios generalmente se realiza con clases situadas en el espacio de nombres System.IO. El primer paso consistiría en obtener todos los archivos que necesita para leer utilizando el método Directory.EnumerateFiles y luego, para cada archivo que corresponda a sus criterios de búsqueda, lea los contenidos utilizando, por ejemplo, el método File.ReadAllBytes.

3

Si realmente desea hacerlo con una expresión lambda recursiva Aquí van:

Action<string, List<string>> discoverFiles = null; 

discoverFiles = new Action<string, List<string>>((dir, list) => 
    { 
     try 
     { 
      foreach (var subDir in Directory.GetDirectories(dir)) 
       discoverFiles(string.Concat(subDir), list); 

      foreach (var dllFile in Directory.GetFiles(dir, "*.dll")) 
      { 
       var fileNameOnly = Path.GetFileName(dllFile); 
       if (!list.Contains(fileNameOnly)) 
        list.Add(fileNameOnly); 
      } 
     } 
     catch (IOException) 
     { 
      // decide what to do here 
     } 
    }); 

// usage: 
var targetList = new List<string>(); 
discoverFiles("c:\\MyDirectory", targetList); 

foreach (var item in targetList) 
    Debug.WriteLine(item); 

Nota: esto es probablemente varias veces más lento (y mucho más difícil de leer/debug/mantener) que la respuestas anteriores, pero no se detiene si hay una excepción de E/S en alguna parte.

+0

Podría hacer algunas refactorizaciones para separar las inquietudes (principalmente la iteración recursiva del filtrado y la adición a la lista), pero he utilizado y evaluado algo similar para una búsqueda de archivos local; funciona casi tan bien como la función incorporada (y eso es cuando se lee desde la memoria caché, si la E/S no se guarda en caché, no hay diferencia) y tiene la ventaja de funcionar incluso cuando algunas rutas son demasiado largas o lo que sea. –

4

esto devuelve simplemente nombres de archivo + extensiones:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\"); 
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories) 
     select i.Name; 

Esto devuelve sólo nombres de los archivos sin extensiones:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\"); 
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories) 
     select System.IO.Path.GetFileNameWithoutExtension(i.Name); 
Cuestiones relacionadas