方法: ディレクトリとファイルを列挙する
.NET Framework Version 4 以降では、ディレクトリとファイルの名前を表す文字列の列挙可能なコレクションを返すメソッドを使用して、ディレクトリとファイルを列挙できます。 また、DirectoryInfo、FileInfo、または FileSystemInfo の各オブジェクトの列挙可能なコレクションを返すメソッドも使用できます。 以前のバージョンの .NET Framework では、これらのコレクションの配列しか取得できませんでした。列挙可能なコレクションは、配列よりもパフォーマンスの点で優れています。
これらのメソッドから取得した列挙可能なコレクションを使用して、List<T> クラスなどのコレクション クラスのコンストラクターの IEnumerable<T> パラメーターを指定することもできます。
ディレクトリまたはファイルの名前のみを取得するには、Directory クラスの列挙メソッドを使用します。 ディレクトリまたはファイルのその他のプロパティを取得するには、DirectoryInfo クラスおよび FileSystemInfo クラスを使用します。 テキスト ファイルの行を列挙することもできます。
列挙可能なコレクションを返すメソッドの説明を次の表に示します。
列挙する対象 |
返される列挙可能なコレクション |
使用するメソッド |
---|---|---|
ディレクトリ |
ディレクトリ名。 |
|
ディレクトリ情報 (DirectoryInfo)。 |
||
ファイル |
ファイル名。 |
|
ファイル情報 (FileInfo)。 |
||
ファイル システム情報 |
ファイル システム エントリ。 |
|
ファイル システム情報 (FileSystemInfo)。 |
||
テキスト ファイルの行 |
ファイルの行。 |
AllDirectories オプションを使用すると親ディレクトリのサブディレクトリ内のすべてのファイルをすぐに列挙できますが、承認されていないアクセスの例外 (UnauthorizedAccessException) が原因で列挙が不完全になる可能性があります。 このような例外が発生する可能性がある場合は、まずディレクトリを列挙してからファイルを列挙することで、例外をキャッチして続行できます。
Windows XP 以前を実行している場合は、列挙されたディレクトリまたはファイルのいずれかに開いているハンドルが残っていると、列挙の後に行われるファイルまたはディレクトリの削除操作に失敗する可能性があります。 この場合は、ガベージ コレクションを強制的に実行して開いているハンドルを削除する必要があります。
ディレクトリ名を列挙するには
Directory.EnumerateDirectories(String) メソッドを使用して、指定したパスに存在する最上位ディレクトリ名のリストを取得します。
Imports System.Collections.Generic Imports System.IO Imports System.Linq Module Module1 Sub Main() Try Dim dirPath As String = "\\archives\2009\reports" ' LINQ query. Dim dirs = From folder In _ Directory.EnumerateDirectories(dirPath) For Each folder In dirs ' Remove path information from string. Console.WriteLine("{0}", _ folder.Substring(folder.LastIndexOf("\") + 1)) Next Console.WriteLine("{0} directories found.", _ dirs.Count.ToString()) ' Optionally create a List collection. Dim workDirs As List(Of String) = New List(Of String)(dirs) Catch UAEx As UnauthorizedAccessException Console.WriteLine(UAEx.Message) Catch PathEx As PathTooLongException Console.WriteLine(PathEx.Message) End Try End Sub End Module
using System; using System.Collections.Generic; using System.IO; using System.Linq; class Program { private static void Main(string[] args) { try { string dirPath = @"\\archives\2009\reports"; // LINQ query. var dirs = from dir in Directory.EnumerateDirectories(dirPath) select dir; // Show results. foreach (var dir in dirs) { // Remove path information from string. Console.WriteLine("{0}", dir.Substring(dir.LastIndexOf("\\") + 1)); } Console.WriteLine("{0} directories found.", dirs.Count<string>().ToString()); // Optionally create a List collection. List<string> workDirs = new List<string>(dirs); } catch (UnauthorizedAccessException UAEx) { Console.WriteLine(UAEx.Message); } catch (PathTooLongException PathEx) { Console.WriteLine(PathEx.Message); } } }
すべてのディレクトリ内のファイル名を列挙するには
Directory.EnumerateFiles(String, String, SearchOption) メソッドを使用してすべてのディレクトリを検索し、指定したパスに存在するファイルのうち指定した検索パターンに一致するファイル名のリストを取得します。
Imports System.IO Imports System.Xml.Linq Module Module1 Sub Main() Try Dim files = From chkFile In Directory.EnumerateFiles("c:\", "*.txt", _ SearchOption.AllDirectories) From line In File.ReadLines(chkFile) Where line.Contains("Microsoft") Select New With {.curFile = chkFile, .curLine = line} For Each f In files Console.WriteLine("{0}\t{1}", f.curFile, f.curLine) Next Console.WriteLine("{0} files found.", _ files.Count.ToString()) Catch UAEx As UnauthorizedAccessException Console.WriteLine(UAEx.Message) Catch PathEx As PathTooLongException Console.WriteLine(PathEx.Message) End Try End Sub End Module
using System; using System.IO; using System.Linq; class Program { static void Main(string[] args) { try { var files = from file in Directory.EnumerateFiles(@"c:\", "*.txt", SearchOption.AllDirectories) from line in File.ReadLines(file) where line.Contains("Microsoft") select new { File = file, Line = line }; foreach (var f in files) { Console.WriteLine("{0}\t{1}", f.File, f.Line); } Console.WriteLine("{0} files found.", files.Count().ToString()); } catch (UnauthorizedAccessException UAEx) { Console.WriteLine(UAEx.Message); } catch (PathTooLongException PathEx) { Console.WriteLine(PathEx.Message); } } }
DirectoryInfo オブジェクトのコレクションを列挙するには
DirectoryInfo.EnumerateDirectories メソッドを使用して、最上位ディレクトリのコレクションを取得します。
' Create a DirectoryInfo of the Program Files directory. Dim dirPrograms As New DirectoryInfo("c:\program files") Dim StartOf2009 As New DateTime(2009, 1, 1) ' LINQ query for all directories created before 2009. Dim dirs = From dir In dirPrograms.EnumerateDirectories() Where dir.CreationTimeUtc < StartOf2009 ' Show results. For Each di As DirectoryInfo In dirs Console.WriteLine("{0}", di.Name) Next
// Create a DirectoryInfo of the Program Files directory. DirectoryInfo dirPrograms = new DirectoryInfo(@"c:\program files"); DateTime StartOf2009 = new DateTime(2009, 01, 01); // LINQ query for all directories created before 2009. var dirs = from dir in dirPrograms.EnumerateDirectories() where dir.CreationTimeUtc < StartOf2009 select new { ProgDir = dir, }; // Show results. foreach (var di in dirs) { Console.WriteLine("{0}", di.ProgDir.Name); }
すべてのディレクトリ内の FileInfo オブジェクトのコレクションを列挙するには
DirectoryInfo.EnumerateFiles メソッドを使用して、すべてのディレクトリ内の指定した検索パターンに一致するファイルのコレクションを取得します。 この例では、まず最上位ディレクトリを列挙して発生の可能性がある承認されていないアクセスの例外をキャッチし、次にファイルを列挙します。
Imports System Imports System.IO Class Program Public Shared Sub Main(ByVal args As String()) ' Create a DirectoryInfo object of the starting directory. Dim diTop As New DirectoryInfo("d:\") Try ' Enumerate the files just in the top directory. For Each fi In diTop.EnumerateFiles() Try ' Display each file over 10 MB; If fi.Length > 10000000 Then Console.WriteLine("{0}" & vbTab & vbTab & "{1}", fi.FullName, fi.Length.ToString("N0")) End If ' Catch unauthorized access to a file. Catch UnAuthTop As UnauthorizedAccessException Console.WriteLine("{0}", UnAuthTop.Message) End Try Next ' Enumerate all subdirectories. For Each di In diTop.EnumerateDirectories("*") Try ' Enumerate each file in each subdirectory. For Each fi In di.EnumerateFiles("*", SearchOption.AllDirectories) Try ' // Display each file over 10 MB; If fi.Length > 10000000 Then Console.WriteLine("{0}" & vbTab & vbTab & "{1}", fi.FullName, fi.Length.ToString("N0")) End If ' Catch unauthorized access to a file. Catch UnAuthFile As UnauthorizedAccessException Console.WriteLine("UnAuthFile: {0}", UnAuthFile.Message) End Try Next ' Catch unauthorized access to a subdirectory. Catch UnAuthSubDir As UnauthorizedAccessException Console.WriteLine("UnAuthSubDir: {0}", UnAuthSubDir.Message) End Try Next ' Catch error in directory path. Catch DirNotFound As DirectoryNotFoundException Console.WriteLine("{0}", DirNotFound.Message) ' Catch unauthorized access to a first tier directory. Catch UnAuthDir As UnauthorizedAccessException Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message) ' Catch paths that are too long. Catch LongPath As PathTooLongException Console.WriteLine("{0}", LongPath.Message) End Try End Sub End Class
using System; using System.IO; class Program { static void Main(string[] args) { // Create a DirectoryInfo object of the starting directory. DirectoryInfo diTop = new DirectoryInfo(@"d:\"); try { // Enumerate the files just in the top directory. foreach (var fi in diTop.EnumerateFiles()) { try { // Display each file over 10 MB; if (fi.Length > 10000000) { Console.WriteLine("{0}\t\t{1}", fi.FullName, fi.Length.ToString("N0")); } } // Catch unauthorized access to a file. catch (UnauthorizedAccessException UnAuthTop) { Console.WriteLine("{0}", UnAuthTop.Message); } } // Enumerate all subdirectories. foreach (var di in diTop.EnumerateDirectories("*")) { try { // Enumerate each file in each subdirectory. foreach (var fi in di.EnumerateFiles("*", SearchOption.AllDirectories)) { try { // Display each file over 10 MB; if (fi.Length > 10000000) { Console.WriteLine("{0}\t\t{1}", fi.FullName, fi.Length.ToString("N0")); } } // Catch unauthorized access to a file. catch (UnauthorizedAccessException UnAuthFile) { Console.WriteLine("UnAuthFile: {0}", UnAuthFile.Message); } } } // Catch unauthorized access to a subdirectory. catch (UnauthorizedAccessException UnAuthSubDir) { Console.WriteLine("UnAuthSubDir: {0}", UnAuthSubDir.Message); } } } // Catch error in directory path. catch (DirectoryNotFoundException DirNotFound) { Console.WriteLine("{0}", DirNotFound.Message); } // Catch unauthorized access to a first tier directory. catch (UnauthorizedAccessException UnAuthDir) { Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message); } // Catch paths that are too long. catch (PathTooLongException LongPath) { Console.WriteLine("{0}", LongPath.Message); } } }
列挙されたディレクトリまたはファイルの開いているハンドルを削除するには
列挙コードを含むカスタム メソッド (または Visual Basic の関数) を作成します。
NoInlining オプションを指定した MethodImplAttribute 属性を新しいメソッドに適用します。 この例を次に示します。
[MethodImplAttribute(MethodImplOptions.NoInlining)] Private void Enumerate()
列挙コードの後に実行する次のメソッド呼び出しを含めます。
GC.Collect() メソッド (パラメーターなし)。