下面的示例演示如何使用递归遍历目录树。递归方法很简洁,但如果目录树很大且嵌套很深,则有可能会引起堆栈溢出异常。
对于所处理的特定异常以及在每个文件和文件夹上执行的特定操作,都只是作为示例提供。您应该修改此代码来满足自己特定的需要。有关更多信息,请参见代码中的注释。
如下图所示:
附代码如下:
using System;namespace 创建人族
{public class RecursiveFileSearch{static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection();static void Main(){// Start with drives if you have to search the entire computer.string[] drives = System.Environment.GetLogicalDrives();foreach (string dr in drives){//去掉这个if循环,那么输出电脑所有硬盘文件名//将d改成你需要查询的目录if (dr.ToLowerInvariant().Contains("d") ) { System.IO.DriveInfo di = new System.IO.DriveInfo(dr);// Here we skip the drive if it is not ready to be read. This// is not necessarily the appropriate action in all scenarios.if (!di.IsReady){Console.WriteLine("The drive {0} could not be read", di.Name);System.IO.File.WriteAllText("C:\\Users\\Administrator\\Desktop\\1.txt", "The drive {0} could not be read");continue;}System.IO.DirectoryInfo rootDir = di.RootDirectory;WalkDirectoryTree(rootDir);}}// Write out all the files that could not be processed.Console.WriteLine("Files with restricted access:");foreach (string s in log){Console.WriteLine(s);System.IO.File.WriteAllText("C:\\Users\\Administrator\\Desktop\\1.txt", s);}// Keep the console window open in debug mode.Console.WriteLine("Press any key");Console.ReadKey();}static void WalkDirectoryTree(System.IO.DirectoryInfo root){System.IO.FileInfo[] files = null;System.IO.DirectoryInfo[] subDirs = null;// First, process all the files directly under this foldertry{//查找你需要的文件类型,这里是所有类型files = root.GetFiles("*.*");}// This is thrown if even one of the files requires permissions greater// than the application provides.catch (UnauthorizedAccessException e){// This code just writes out the message and continues to recurse.// You may decide to do something different here. For example, you// can try to elevate your privileges and access the file again.log.Add(e.Message);}catch (System.IO.DirectoryNotFoundException e){Console.WriteLine(e.Message);System.IO.File.WriteAllText("C:\\Users\\Administrator\\Desktop\\1.txt", e.Message);}if (files != null){foreach (System.IO.FileInfo fi in files){// In this example, we only access the existing FileInfo object. If we// want to open, delete or modify the file, then// a try-catch block is required here to handle the case// where the file has been deleted since the call to TraverseTree().Console.WriteLine(fi.FullName);//System.IO.File.AppendAllText ("C:\\Users\\Administrator\\Desktop\\1.txt", fi.FullName);System.IO.File.AppendAllText("C:\\Users\\Administrator\\Desktop\\1.txt", fi.FullName + "\n");}// Now find all the subdirectories under this directory.subDirs = root.GetDirectories();foreach (System.IO.DirectoryInfo dirInfo in subDirs){// Resursive call for each subdirectory.WalkDirectoryTree(dirInfo);}}}}}
下面的示例演示在不使用递归的情况下如何循环访问目录树中的文件和文件夹。该技术使用泛型 Stack<(Of <(T>)>) 集合类型,该类型是一个后进先出 (LIFO) 堆栈。
对于所处理的特定异常以及在每个文件和文件夹上执行的特定操作,都只是作为示例提供。您应该修改此代码来满足自己特定的需要。有关更多信息,请参见代码中的注释。
using System;
using System.Collections.Generic;namespace myns
{public class StackBasedIteration{static void Main(string[] args){// Specify the starting folder on the command line, or in // Visual Studio in the Project > Properties > Debug pane.TraverseTree("G:\\");Console.WriteLine("Press any key");Console.ReadKey();}public static void TraverseTree(string root){// Data structure to hold names of subfolders to be// examined for files.Stack<string> dirs = new Stack<string>(20);if (!System.IO.Directory.Exists(root)){throw new ArgumentException();}dirs.Push(root);while (dirs.Count > 0){string currentDir = dirs.Pop();string[] subDirs;try{subDirs = System.IO.Directory.GetDirectories(currentDir);}// An UnauthorizedAccessException exception will be thrown if we do not have// discovery permission on a folder or file. It may or may not be acceptable // to ignore the exception and continue enumerating the remaining files and // folders. It is also possible (but unlikely) that a DirectoryNotFound exception // will be raised. This will happen if currentDir has been deleted by// another application or thread after our call to Directory.Exists. The // choice of which exceptions to catch depends entirely on the specific task // you are intending to perform and also on how much you know with certainty // about the systems on which this code will run.catch (UnauthorizedAccessException e){Console.WriteLine(e.Message);continue;}catch (System.IO.DirectoryNotFoundException e){Console.WriteLine(e.Message);continue;}string[] files = null;try{files = System.IO.Directory.GetFiles(currentDir);}catch (UnauthorizedAccessException e){Console.WriteLine(e.Message);continue;}catch (System.IO.DirectoryNotFoundException e){Console.WriteLine(e.Message);continue;}// Perform the required action on each file here.// Modify this block to perform your required task.foreach (string file in files){try{// Perform whatever action is required in your scenario.System.IO.FileInfo fi = new System.IO.FileInfo(file);Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);}catch (System.IO.FileNotFoundException e){// If file was deleted by a separate application// or thread since the call to TraverseTree()// then just continue.Console.WriteLine(e.Message);continue;}}// Push the subdirectories onto the stack for traversal.// This could also be done before handing the files.foreach (string str in subDirs)dirs.Push(str);}}}}