Le nuove API del .NET Framework 4.0 per enumerare file e directory

Il .NET Framework 4.0 apporta piccole, ma interessanti modiche alla BCL che con una serie di script si vogliono illustrare per capirne al meglio l'utilità. Tra i cambiamenti presenti, vi è un importante adeguamento delle API in modo che queste possano essere sfruttate al meglio insieme a LINQ. Laddove, infatti, una funzione possa restituire una lista, se questa può essere di molteplici elementi e richiedere molto tempo, in luogo di un List<T> o di un Array, si preferisce restituire un IEnumerable<T>. Un oggetto che implementa questa interfaccia può essere sfogliato con un foreach e posticipa il consumo delle informazioni al momento in cui le si richiedono.

Ne sono un esempio la classe File e Directory (o le rispettive FileInfo e DirectoryInfo) che dispongono dei metodi GetFiles e GetDirectories, i quale a loro volta restituiscono un array. Questo comporta l'attesa per l'intero recupero della lista dei files e delle directory, prima di poterlo consumare. I nuovi metodi EnumerateFiles e EnumerateDirectories restituiscono invece un IEnumerable permettendo di consumare subito l'enumatore interno delle API di Windows, di mostrare un progress e di effettuare query LINQ.

Nel seguente esempio si sfoglia la cartella My Documents alla ricerca di files con estensione *.txt combinando entrambi i metodi.

DirectoryInfo docDir = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
var groups = from d in docDir.EnumerateDirectories("*", SearchOption.AllDirectories)
             from f in d.EnumerateFiles("*.txt")
             group f by f.Directory into g
             select g;

foreach (var g in groups)
{
    Console.WriteLine("Files into {0}", g.Key);
    foreach (var f in g)
        Console.WriteLine("\t{0}", f.Name);
}

E' bene sottolineare che questo non aumenta le prestazioni di ricerca, poiché l'enumerazione su disco dev'essere comunque fatta, ma è possibile ottenere dei tagli netti di tempo qualora l'elemento da cercare sia tra i primi elementi restituiti dall'enumeratore, consentendo di fermare la ricerca.