2010-10-22 31 views
17

En C#, ¿cómo puedo verificar si existe un archivo específico en un directorio o cualquiera de sus subdirectorios?Cómo verificar si existe un archivo específico en el directorio o cualquiera de sus subdirectorios

System.IO.File.Exists solo parece aceptar un solo parámetro sin sobrecargas para buscar subdirectorios.

puedo hacerlo con LINQ y System.IO.Directory.GetFiles utilizando el SearchOption.AllDirectories sobrecarga, pero que parece un poco de mano dura.

var MyList = from f in Directory.GetFiles(tempScanStorage, "foo.txt", SearchOption.AllDirectories) 
      where System.IO.Path.GetFileName(f).ToUpper().Contains(foo) 
      select f; 

foreach (var x in MyList) 
{ 
    returnVal = x.ToString(); 
} 

Respuesta

33

Si está buscando un único nombre de archivo específico, usar *.* es muy difícil. Prueba esto:

var file = Directory.GetFiles(tempScanStorage, foo, SearchOption.AllDirectories) 
        .FirstOrDefault(); 
if (file == null) 
{ 
    // Handle the file not being found 
} 
else 
{ 
    // The file variable has the *first* occurrence of that filename 
} 

Tenga en cuenta que esto no es exactamente lo que hace su consulta actual - debido a que su consulta actual encontraría "xbary.txt" si foo fue sólo bar. No sé si eso es intencional o no.

Si quieres saber sobre múltiples coincidencias, no deberías usar FirstOrDefault() por supuesto. No está claro exactamente lo que estás tratando de hacer, lo que hace que sea difícil dar consejos más concretos.

Tenga en cuenta que en .NET 4 también hay Directory.EnumerateFiles que pueden funcionar mejor o peor. Dudo mucho que marque la diferencia cuando busque un archivo específico (en lugar de todos los archivos en el directorio y los subdirectorios), pero al menos vale la pena saberlo. EDITAR: Como se señaló en los comentarios, es can make a difference if you don't have permission to see all the files in a directory.

+0

Sí, estoy buscando encontrar un solo archivo específico. He actualizado el '*. *'. Gracias por la solución apretada. – Dhaust

+3

EnumerateFiles hace una diferencia si está escaneando directorios donde no tiene permisos para todo (por ejemplo, desde el nivel de unidad donde hay una RecycleBin). cf http://stackoverflow.com/questions/1393178 para una solución si se encuentra con ese caso. – Malcolm

+0

@Malcolm: Gracias; editado en la respuesta. –

5

La alternativa es escribir la función de búsqueda de sí mismo, uno de ellos debe trabajar:

private bool FileExists(string rootpath, string filename) 
    { 
     if(File.Exists(Path.Combine(rootpath, filename))) 
      return true; 

     foreach(string subDir in Directory.GetDirectories(rootpath, "*", SearchOption.AllDirectories)) 
     { 
      if(File.Exists(Path.Combine(subDir, filename))) 
      return true; 
     } 

     return false; 
    } 

    private bool FileExistsRecursive(string rootPath, string filename) 
    { 
     if(File.Exists(Path.Combine(rootPath, filename))) 
      return true; 

     foreach (string subDir in Directory.GetDirectories(rootPath)) 
     { 
      return FileExistsRecursive(subDir, filename); 
     } 

     return false; 
    } 

La primera método todavía extrae todos los nombres de directorio y sería más lento cuando hay muchos subdirectorios pero el archivo está cerca de la parte superior.

El segundo es recursivo, que sería más lento en los escenarios de 'peor caso' pero más rápido cuando hay muchos subdires anidados pero el archivo está en un directorio de nivel superior.

0

Esta es una función de búsqueda recursiva que se iniciará tan pronto como encuentre el archivo que ha especificado. Tenga en cuenta que los parámetros deben especificarse como fileName (por ejemplo, testdb.bak) y directorio (por ejemplo, c: \ test).

Tenga en cuenta que esto puede ser bastante lento si hace esto en un directorio con una gran cantidad de subdirectorios y archivos.

private static bool CheckIfFileExists(string fileName, string directory) {    
     var exists = false; 
     var fileNameToCheck = Path.Combine(directory, fileName); 
     if (Directory.Exists(directory)) { 
      //check directory for file 
      exists = Directory.GetFiles(directory).Any(x => x.Equals(fileNameToCheck, StringComparison.OrdinalIgnoreCase)); 

      //check subdirectories for file 
      if (!exists) { 
       foreach (var dir in Directory.GetDirectories(directory)) { 
        exists = CheckIfFileExists(fileName, dir);        

        if (exists) break; 
       } 
      } 
     } 
     return exists; 
    } 
1

para comprobar si hay cualquier archivo existente en el directorio específico haga lo siguiente Nota: "uploadedfiles" es el nombre de la carpeta.

File.Exists (Server.MapPath ("/") uploadedfiles)

Disfrute de Codificación

Cuestiones relacionadas