HOW TO:列舉目錄和檔案

從 .NET Framework 4 版開始,您就可以使用傳回目錄和檔案名稱字串之可列舉集合的方法來列舉目錄和檔案。 您也可以使用傳回 DirectoryInfoFileInfoFileSystemInfo 物件之可列舉集合的方法。 在舊版 .NET Framework 中,您只能取得這些集合的陣列。可列舉集合會比陣列提供更好的效能。

您也可以使用透過這些方法取得的可列舉集合,針對 List<T> 類別等集合類別的建構函式提供 IEnumerable<T> 參數。

如果您只想要取得目錄或檔案的名稱,請使用 Directory 類別的列舉方法。 如果您想要取得目錄或檔案的其他屬性,請使用 DirectoryInfoFileSystemInfo 類別。 您也可以列舉文字檔的行。

下表提供傳回可列舉集合之方法的指南。

若要列舉

要傳回的可列舉集合

要使用的方法

目錄

目錄名稱。

Directory.EnumerateDirectories

目錄資訊 (DirectoryInfo)。

DirectoryInfo.EnumerateDirectories

檔案

檔案名稱。

Directory.EnumerateFiles

檔案資訊 (FileInfo)。

DirectoryInfo.EnumerateFiles

檔案系統資訊

檔案系統項目。

Directory.EnumerateFileSystemEntries

檔案系統資訊 (FileSystemInfo)。

DirectoryInfo.EnumerateFileSystemInfos

文字檔的行

檔案的行。

File.ReadLines

雖然您可以使用 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);
            }
    
        }
    }
    

若要移除列舉的目錄或檔案上的開放控制代碼

  1. 建立自訂方法 (在 Visual Basic 中為函式) 來包含列舉型別程式碼。

  2. 將包含 NoInlining 選項的 MethodImplAttribute 屬性套用至新方法。 例如:

    [MethodImplAttribute(MethodImplOptions.NoInlining)]
    Private void Enumerate()
    
  3. 包含下列方法呼叫,以便在列舉型別程式碼後面執行:

請參閱

概念

基本檔案 I/O