今回は、ちょっとした補足事項です。
.NET 4.0になり、今まで存在していたメソッドの遅延評価版が追加されたクラスが
いくつかあります。そのうちの一つが
System.IO.Directory
クラスで、以下のメソッドが追加されています。
- EnumerateFiles
- EnumerateDirectories
- EnumerateFileSystemEntries
上記のメソッドは、従来から存在していた以下のメソッドの遅延評価版です。
- GetFiles
- GetDirectories
- GetFileSystemEntries
書式は以下の通り。
public static IEnumerable<string> EnumerateFiles( string path ) public static IEnumerable<string> EnumerateFiles( string path, string searchPattern ) public static IEnumerable<string> EnumerateFiles( string path, string searchPattern, SearchOption searchOption ) public static IEnumerable<string> EnumerateDirectories( string path ) public static IEnumerable<string> EnumerateDirectories( string path, string searchPattern ) public static IEnumerable<string> EnumerateDirectories( string path, string searchPattern, SearchOption searchOption ) public static IEnumerable<string> EnumerateFileSystemEntries( string path ) public static IEnumerable<string> EnumerateFileSystemEntries( string path, string searchPattern ) public static IEnumerable<string> EnumerateFileSystemEntries( string path, string searchPattern, SearchOption searchOption )
どのメソッドも、戻り値がIEnumerable
遅延評価されるということは、LINQで処理しやすいということです。
今までだと、例えばGetFilesメソッドは内部で合致する情報のコレクションを
構築してから値を返してくれていました。つまり、内容を列挙する場合
完全にコレクションが完成するまで待つ必要がありました。
EnumerableFilesメソッドの場合は、コレクションが完成する前に列挙を始める事が
可能です。LINQを利用すると、whereで必要な情報のみに絞り込んだりするのも楽です。
以下、サンプルです。
このサンプルでは、それぞれのメソッドで列挙処理が開始されるまでの
時間を計測して表示しています。
#region LinqSamples-49 public class LinqSamples49 : IExecutable { public void Execute() { // // Directory.EnumerateFilesメソッドは、従来までの // Directory.GetFilesメソッドと同じ動作するメソッドである。 // // 違いは、戻り値がIEnumerable<string>となっており // 遅延評価される。 // // GetFilesメソッドの場合は、全リストを構築してから // 戻り値が返却されるので、コレクションが構築されるまで // 待機する必要があるが、EnumerateFilesメソッドの場合は // コレクション全体が返される前に、列挙可能である。 // // EnumerateDirectoriesメソッド及びEnumerateFileSystemEntriesメソッドも上記と同様。 // var path = @"c:\windows"; var filter = @"*.exe"; var watch = Stopwatch.StartNew(); var elapsed = string.Empty; // // EnumerateFiles. // var query = from file in Directory.EnumerateFiles(path, filter, SearchOption.AllDirectories) select file; foreach (var item in query) { if (watch != null) { watch.Stop(); elapsed = watch.Elapsed.ToString(); watch = null; } //Console.WriteLine(item); } Console.WriteLine("================== EnumereteFiles : {0} ==================", elapsed); // // EnumerateDirectories. // watch = Stopwatch.StartNew(); elapsed = string.Empty; query = from directory in Directory.EnumerateDirectories(path) select directory; foreach (var item in query) { if (watch != null) { watch.Stop(); elapsed = watch.Elapsed.ToString(); watch = null; } //Console.WriteLine(item); } Console.WriteLine("================== EnumerateDirectories : {0} ==================", elapsed); // // EnumerateFileSystemEntries. // watch = Stopwatch.StartNew(); elapsed = string.Empty; query = from directory in Directory.EnumerateFileSystemEntries(path) select directory; foreach (var item in query) { if (watch != null) { watch.Stop(); elapsed = watch.Elapsed.ToString(); watch = null; } //Console.WriteLine(item); } Console.WriteLine("================== EnumerateFileSystemEntries : {0} ==================", elapsed); // // GetFiles. // watch = Stopwatch.StartNew(); elapsed = string.Empty; var files = Directory.GetFiles(path, filter, SearchOption.AllDirectories); foreach (var item in files) { if (watch != null) { watch.Stop(); elapsed = watch.Elapsed.ToString(); watch = null; } //Console.WriteLine(item); } Console.WriteLine("================== GetFiles : {0} ==================", elapsed); // // GetDirectories. // watch = Stopwatch.StartNew(); elapsed = string.Empty; var dirs = Directory.GetDirectories(path); foreach (var item in dirs) { if (watch != null) { watch.Stop(); elapsed = watch.Elapsed.ToString(); watch = null; } //Console.WriteLine(item); } Console.WriteLine("================== GetDirectories : {0} ==================", elapsed); // // GetFileSystemEntries. // watch = Stopwatch.StartNew(); elapsed = string.Empty; var entries = Directory.GetFileSystemEntries(path); foreach (var item in entries) { if (watch != null) { watch.Stop(); elapsed = watch.Elapsed.ToString(); watch = null; } //Console.WriteLine(item); } Console.WriteLine("================== GetFileSystemEntries : {0} ==================", elapsed); } } #endregion
実行結果は以下の通りです。
================== EnumereteFiles : 00:00:00.0031096 ================== ================== EnumerateDirectories : 00:00:00.0004081 ================== ================== EnumerateFileSystemEntries : 00:00:00.0002966 ================== ================== GetFiles : 00:00:02.4642173 ================== ================== GetDirectories : 00:00:00.0024564 ================== ================== GetFileSystemEntries : 00:00:00.0036865 ==================
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ