HOW TO:列舉目錄和檔案
從 .NET Framework 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() 方法 (無參數)。