方法: ディレクトリとファイルを列挙する

列挙可能なコレクションでは、ディレクトリとファイルの大きなコレクションを操作する際に配列よりも優れたパフォーマンスが得られます。 ディレクトリとファイルを列挙するには、列挙可能なディレクトリ名またはファイル名のコレクション、またはその DirectoryInfoFileInfo、または FileSystemInfo オブジェクトを返すメソッドを使用します。

ディレクトリまたはファイルの名前のみを検索して返す場合は、Directory クラスの列挙メソッドを使用します。 ディレクトリまたはファイルの他のプロパティを検索して返す場合は、DirectoryInfo および FileSystemInfo クラスを使用します。

List<T> のようなコレクション クラスのコンストラクターの IEnumerable<T> パラメーターとして、このようなメソッドの列挙可能なコレクションを使用できます。

次の表は、ファイルとディレクトリの列挙可能なコレクションを返すメソッドをまとめたものです。

検索して返すもの 使用するメソッド
ディレクトリ名 Directory.EnumerateDirectories
ディレクトリ情報 (DirectoryInfo) DirectoryInfo.EnumerateDirectories
ファイル名 Directory.EnumerateFiles
ファイル情報 (FileInfo) DirectoryInfo.EnumerateFiles
ファイル システムのエントリ名 Directory.EnumerateFileSystemEntries
ファイル システムのエントリ情報 (FileSystemInfo) DirectoryInfo.EnumerateFileSystemInfos
ディレクトリとファイルの名前 Directory.EnumerateFileSystemEntries

注意

省略可能な SearchOption 列挙型の AllDirectories オプションを使用すると、親ディレクトリのサブディレクトリ内にあるすべてのファイルをすぐに列挙できますが、UnauthorizedAccessException のエラーによって列挙が不完全になる可能性があります。 このような例外をキャッチするには、まずディレクトリを列挙してからファイルを列挙します。

次に例を示します。 Directory クラスを使用する

次の例では、Directory.EnumerateDirectories(String) メソッドを使用して、指定されたパスの最上位レベルのディレクトリ名のリストを取得します。

using System;
using System.Collections.Generic;
using System.IO;

class Program
{
    private static void Main(string[] args)
    {
        try
        {
            // Set a variable to the My Documents path.
            string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            List<string> dirs = new List<string>(Directory.EnumerateDirectories(docPath));

            foreach (var dir in dirs)
            {
                Console.WriteLine($"{dir.Substring(dir.LastIndexOf(Path.DirectorySeparatorChar) + 1)}");
            }
            Console.WriteLine($"{dirs.Count} directories found.");
        }
        catch (UnauthorizedAccessException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch (PathTooLongException ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}
Imports System.Collections.Generic
Imports System.IO

Module Module1

    Sub Main()
        Try
            Dim dirPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

            Dim dirs As List(Of String) = New List(Of String)(Directory.EnumerateDirectories(dirPath))

            For Each folder In dirs
                Console.WriteLine($"{dir.Substring(dir.LastIndexOf(Path.DirectorySeparatorChar) + 1)}")
            Next
            Console.WriteLine($"{dirs.Count} directories found.")
        Catch ex As UnauthorizedAccessException
            Console.WriteLine(ex.Message)
        Catch ex As PathTooLongException
            Console.WriteLine(ex.Message)
        End Try

    End Sub
End Module

次の例では、Directory.EnumerateFiles(String, String, SearchOption) メソッドを使用して、特定のパターンに一致するディレクトリとサブディレクトリ内にあるすべてのファイル名を再帰的に列挙します。 次に、各ファイルの各行を読み取り、指定された文字列を含む行をファイル名とパスと共に表示します。

using System;
using System.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            // Set a variable to the My Documents path.
            string docPath =
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            var files = from file in Directory.EnumerateFiles(docPath, "*.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($"{f.File}\t{f.Line}");
            }
            Console.WriteLine($"{files.Count().ToString()} files found.");
        }
        catch (UnauthorizedAccessException uAEx)
        {
            Console.WriteLine(uAEx.Message);
        }
        catch (PathTooLongException pathEx)
        {
            Console.WriteLine(pathEx.Message);
        }
    }
}
Imports System.IO
Imports System.Xml.Linq

Module Module1

    Sub Main()
        Try
            Dim docPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
            Dim files = From chkFile In Directory.EnumerateFiles(docPath, "*.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($"{f.File}\t{f.Line}")
            Next
            Console.WriteLine($"{files.Count} files found.")
        Catch uAEx As UnauthorizedAccessException
            Console.WriteLine(uAEx.Message)
        Catch pathEx As PathTooLongException
            Console.WriteLine(pathEx.Message)
        End Try
    End Sub
End Module

次に例を示します。 DirectoryInfo クラスを使用する

次の例では、DirectoryInfo.EnumerateDirectories メソッドを使用して、CreationTimeUtc が特定の DateTime 値より前の最上位ディレクトリのコレクションを一覧表示します。

using System;
using System.IO;

namespace EnumDir
{
    class Program
    {
        static void Main(string[] args)
        {
            // Set a variable to the Documents path.
            string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            DirectoryInfo dirPrograms = new DirectoryInfo(docPath);
            DateTime StartOf2009 = new DateTime(2009, 01, 01);

            var dirs = from dir in dirPrograms.EnumerateDirectories()
            where dir.CreationTimeUtc > StartOf2009
            select new
            {
                ProgDir = dir,
            };

            foreach (var di in dirs)
            {
                Console.WriteLine($"{di.ProgDir.Name}");
            }
        }
    }
}
// </Snippet1>
Imports System.IO

Module Module1

    Sub Main()

        Dim dirPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
        Dim dirPrograms As New DirectoryInfo(dirPath)
        Dim StartOf2009 As New DateTime(2009, 1, 1)

        Dim dirs = From dir In dirPrograms.EnumerateDirectories()
                   Where dir.CreationTimeUtc > StartOf2009

        For Each di As DirectoryInfo In dirs
            Console.WriteLine("{0}", di.Name)
        Next

    End Sub

End Module

次の例では、DirectoryInfo.EnumerateFiles メソッドを使用して、Length が 10 MB を超えるすべてのファイルを一覧表示します。 この例では、まず、最上位レベルのディレクトリを列挙して考えられる未承認アクセス例外をキャッチしてから、ファイルを列挙します。

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        // Set a variable to the My Documents path.
        string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

        DirectoryInfo diTop = new DirectoryInfo(docPath);

        try
        {
            foreach (var fi in diTop.EnumerateFiles())
            {
                try
                {
                    // Display each file over 10 MB;
                    if (fi.Length > 10000000)
                    {
                        Console.WriteLine($"{fi.FullName}\t\t{fi.Length.ToString("N0")}");
                    }
                }
                catch (UnauthorizedAccessException unAuthTop)
                {
                    Console.WriteLine($"{unAuthTop.Message}");
                }
            }

            foreach (var di in diTop.EnumerateDirectories("*"))
            {
                try
                {
                    foreach (var fi in di.EnumerateFiles("*", SearchOption.AllDirectories))
                    {
                        try
                        {
                            // Display each file over 10 MB;
                            if (fi.Length > 10000000)
                            {
                                Console.WriteLine($"{fi.FullName}\t\t{fi.Length.ToString("N0")}");
                            }
                        }
                        catch (UnauthorizedAccessException unAuthFile)
                        {
                            Console.WriteLine($"unAuthFile: {unAuthFile.Message}");
                        }
                    }
                }
                catch (UnauthorizedAccessException unAuthSubDir)
                {
                    Console.WriteLine($"unAuthSubDir: {unAuthSubDir.Message}");
                }
            }
        }
        catch (DirectoryNotFoundException dirNotFound)
        {
            Console.WriteLine($"{dirNotFound.Message}");
        }
        catch (UnauthorizedAccessException unAuthDir)
        {
            Console.WriteLine($"unAuthDir: {unAuthDir.Message}");
        }
        catch (PathTooLongException longPath)
        {
            Console.WriteLine($"{longPath.Message}");
        }
    }
}
Imports System.IO

Class Program
    Public Shared Sub Main(ByVal args As String())
        Dim dirPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
        Dim diTop As New DirectoryInfo(dirPath)
        Try
            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 unAuthTop As UnauthorizedAccessException
                    Console.WriteLine($"{unAuthTop.Message}")
                End Try
            Next

            For Each di In diTop.EnumerateDirectories("*")
                Try
                    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 unAuthFile As UnauthorizedAccessException
                            Console.WriteLine($"unAuthFile: {unAuthFile.Message}")
                        End Try
                    Next
                Catch unAuthSubDir As UnauthorizedAccessException
                    Console.WriteLine($"unAuthSubDir: {unAuthSubDir.Message}")
                End Try
            Next
        Catch dirNotFound As DirectoryNotFoundException
            Console.WriteLine($"{dirNotFound.Message}")
        Catch unAuthDir As UnauthorizedAccessException
            Console.WriteLine($"unAuthDir: {unAuthDir.Message}")
        Catch longPath As PathTooLongException
            Console.WriteLine($"{longPath.Message}")
        End Try
    End Sub
End Class

関連項目