HOW TO:列舉目錄和檔案How to: Enumerate directories and files

當您使用目錄和檔案的大型集合時,相較於陣列,可列舉的集合會提供更佳的效能。Enumerable collections provide better performance than arrays when you work with large collections of directories and files. 若要列舉目錄和檔案,請使用能夠傳回可列舉目錄或檔案名稱、或是其 DirectoryInfoFileInfoFileSystemInfo 物件集合的方法。To enumerate directories and files, use methods that return an enumerable collection of directory or file names, or their DirectoryInfo, FileInfo, or FileSystemInfo objects.

如果您想要搜尋並只傳回目錄或檔案的名稱,請使用 Directory 類別的列舉方法。If you want to search and return only the names of directories or files, use the enumeration methods of the Directory class. 如果您想要搜尋並傳回目錄或檔案的其他屬性,請使用 DirectoryInfoFileSystemInfo 類別。If you want to search and return other properties of directories or files, use the DirectoryInfo and FileSystemInfo classes.

您可以使用來自這些方法的可列舉集合,作為 List<T> 等集合類別建構函式的 IEnumerable<T> 參數。You can use enumerable collections from these methods as the IEnumerable<T> parameter for constructors of collection classes like List<T>.

下表摘要說明能夠傳回可列舉檔案和目錄集合的方法:The following table summarizes the methods that return enumerable collections of files and directories:

搜尋並傳回To search and return 使用方法Use method
目錄名稱Directory names Directory.EnumerateDirectories
虛擬資訊 (DirectoryInfo)Directory information (DirectoryInfo) DirectoryInfo.EnumerateDirectories
檔案名稱File names Directory.EnumerateFiles
檔案資訊 (FileInfo)File information (FileInfo) DirectoryInfo.EnumerateFiles
檔案系統項目名稱File system entry names Directory.EnumerateFileSystemEntries
檔案系統項目資訊 (FileSystemInfo)File system entry information (FileSystemInfo) DirectoryInfo.EnumerateFileSystemInfos
目錄和檔案名稱Directory and file names Directory.EnumerateFileSystemEntries

注意

雖然您可以使用選擇性 SearchOption 列舉的 AllDirectories 選項立即列舉父目錄中子目錄的所有檔案,但 UnauthorizedAccessException 錯誤可能會使列舉不完整。Although you can immediately enumerate all the files in the subdirectories of a parent directory by using the AllDirectories option of the optional SearchOption enumeration, UnauthorizedAccessException errors may make the enumeration incomplete. 您可以先列舉目錄再列舉檔案來攔截這些例外狀況。You can catch these exceptions by first enumerating directories and then enumerating files.

例如:使用 Directory 類別Examples: Use the Directory class

下列範例使用 Directory.EnumerateDirectories(String) 方法,在所指定路徑中取得最上層目錄名稱的清單。The following example uses the Directory.EnumerateDirectories(String) method to get a list of the top-level directory names in a specified path.

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) 方法,以遞迴方式列舉目錄和子目錄中符合特定模式的所有檔案名稱。The following example uses the Directory.EnumerateFiles(String, String, SearchOption) method to recursively enumerate all file names in a directory and subdirectories that match a certain pattern. 然後,它會讀取每個檔案的每一行,並顯示包含指定字串的行,以及其檔名和路徑。It then reads each line of each file and displays the lines that contain a specified string, with their filenames and paths.

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 類別Examples: Use the DirectoryInfo class

下列範例使用 DirectoryInfo.EnumerateDirectories 方法,列出其 CreationTimeUtc 早於特定 DateTime 值的最上層目錄集合。The following example uses the DirectoryInfo.EnumerateDirectories method to list a collection of top-level directories whose CreationTimeUtc is earlier than a certain DateTime value.

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 的所有檔案。The following example uses the DirectoryInfo.EnumerateFiles method to list all files whose Length exceeds 10MB. 此範例會先列舉最上層目錄來攔截可能未經授權的存取例外狀況,再列舉檔案。This example first enumerates the top-level directories, to catch possible unauthorized access exceptions, and then enumerates the files.

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("NO")}");
                    }
                }
                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("NO")}");
                            }
                        }
                        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

另請參閱See also