Primero, perdone mi inglés pobre; o) Tuve un problema que me llevó a esta página: enumerar archivos de un directorio y sus subdirectorios sin bloquear en una excepción no autorizada y, como el nuevo método de .Net 4 DirectoryInfo .Enumerar ..., obtener el primer resultado antes del final de toda la consulta.
Con la ayuda de varios ejemplos que se encuentran aquí y allá en la web, que finalmente escribir este método:
public static IEnumerable<FileInfo> EnumerateFiles_Recursive(this DirectoryInfo directory, string searchPattern, SearchOption searchOption, Func<DirectoryInfo, Exception, bool> handleExceptionAccess)
{
Queue<DirectoryInfo> subDirectories = new Queue<DirectoryInfo>();
IEnumerable<FileSystemInfo> entries = null;
// Try to get an enumerator on fileSystemInfos of directory
try
{
entries = directory.EnumerateFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);
}
catch (Exception e)
{
// If there's a callback delegate and this delegate return true, we don't throw the exception
if (handleExceptionAccess == null || !handleExceptionAccess(directory, e))
throw;
// If the exception wasn't throw, we make entries reference an empty collection
entries = EmptyFileSystemInfos;
}
// Yield return file entries of the directory and enqueue the subdirectories
foreach (FileSystemInfo entrie in entries)
{
if (entrie is FileInfo)
yield return (FileInfo)entrie;
else if (entrie is DirectoryInfo)
subDirectories.Enqueue((DirectoryInfo)entrie);
}
// If recursive search, we make recursive call on the method to yield return entries of the subdirectories.
if (searchOption == SearchOption.AllDirectories)
{
DirectoryInfo subDir = null;
while (subDirectories.Count > 0)
{
subDir = subDirectories.Dequeue();
foreach (FileInfo file in subDir.EnumerateFiles_Recursive(searchPattern, searchOption, handleExceptionAccess))
{
yield return file;
}
}
}
else
subDirectories.Clear();
}
utilizo una cola y un método recursivo para mantener el orden tradicional (contenido del directorio y contenido del primer subdirectorio y sus propios subdirectorios y luego el contenido del segundo ...). El parámetro "handleExceptionAccess" es solo una llamada a función cuando se lanza una excepción con un directorio; la función debe devolver verdadero para indicar que la excepción debe ser ignorada.
Con esta méthode, puede escribir:
DirectoryInfo dir = new DirectoryInfo("c:\\temp");
long size = dir.EnumerateFiles_Recursive("*", SearchOption.AllDirectories, (d, ex) => true).Sum(f => f.Length);
Y aquí estamos: todos excepto cuando se trata de enumerar un directorio será ignorar!
Esperanza esta ayuda
Lionel
PD: por una razón que no puedo explicar, mi método es más rápido que el marco de un 4 ...
PPS: se puede conseguir mi soluciones de prueba con la fuente de esos métodos: aquí TestDirEnumerate. Escribo EnumerateFiles_Recursive, EnumerateFiles_NonRecursive (uso una cola para evitar la recursión) y EnumerateFiles_NonRecursive_TraditionalOrder (uso una pila de cola para evitar la recursión y mantener el orden tradicional). Mantener esos 3 métodos no tiene interés, los escribo solo para probar el mejor. Pienso guardar solo el último. También escribí el equivalente para EnumerateFileSystemInfos y EnumerateDirectories.
Gracias por eso :) – ThePower