详解如何在C#中循环访问目录树

 更新时间:2024年08月26日 10:13:04   作者:白话Learning  
在C#中,访问文件系统是常见的需求之一,有时我们需要遍历目录树以执行某些操作,例如搜索文件、计算目录大小或执行批量处理,本文将详细介绍如何在C#中循环访问目录树,并提供一个完整的示例,需要的朋友可以参考下

一、目录树遍历的概念

目录树遍历是一种在文件系统中访问所有目录和文件的过程。它通常从根目录开始,然后递归地访问每个子目录,直到达到树的末端。

二、使用System.IO命名空间

在C#中,System.IO命名空间提供了用于文件和目录操作的类。要使用这些类,你需要在代码顶部添加以下命名空间引用:

using System.IO;

三、DirectoryInfo和FileInfo类

DirectoryInfo类用于表示目录,而FileInfo类用于表示文件。这两个类提供了多种方法来操作文件和目录。

  • DirectoryInfo:提供创建、移动、删除目录等方法。
  • FileInfo:提供创建、复制、删除、打开文件等方法。

四、递归遍历目录树

递归是访问目录树的一种常见方法。以下是一个递归函数的基本结构,用于遍历目录:

void TraverseDirectory(DirectoryInfo directory)
{
    // 处理当前目录下的文件
    FileInfo[] files = directory.GetFiles();
    foreach (FileInfo file in files)
    {
        // 对文件执行操作
    }

    // 递归访问子目录
    DirectoryInfo[] subDirectories = directory.GetDirectories();
    foreach (DirectoryInfo subDirectory in subDirectories)
    {
        TraverseDirectory(subDirectory);
    }
}

五、示例:列出目录树中的所有文件和文件夹

以下是一个完整的示例,该示例列出指定根目录下的所有文件和文件夹:

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string rootPath = @"C:\Your\Directory\Path"; // 替换为你的根目录路径
        DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);

        if (rootDirectory.Exists)
        {
            TraverseDirectory(rootDirectory);
        }
        else
        {
            Console.WriteLine("The specified directory does not exist.");
        }
    }

    static void TraverseDirectory(DirectoryInfo directory)
    {
        // 处理当前目录下的文件
        FileInfo[] files = directory.GetFiles();
        foreach (FileInfo file in files)
        {
            Console.WriteLine($"File: {file.FullName}");
        }

        // 递归访问子目录
        DirectoryInfo[] subDirectories = directory.GetDirectories();
        foreach (DirectoryInfo subDirectory in subDirectories)
        {
            Console.WriteLine($"Directory: {subDirectory.FullName}");
            TraverseDirectory(subDirectory);
        }
    }
}

在运行此程序时,它将打印出指定根目录下的所有文件和文件夹的路径。

六、异常处理

在处理文件和目录时,可能会遇到各种异常,如权限不足、路径不存在等。因此,应该使用try-catch块来处理这些潜在的错误:

try
{
    TraverseDirectory(rootDirectory);
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("Access denied to one or more directories.");
}
catch (DirectoryNotFoundException)
{
    Console.WriteLine("The specified directory was not found.");
}
catch (Exception e)
{
    Console.WriteLine($"An unexpected error occurred: {e.Message}");
}

七、迭代方法

迭代方法利用栈(或队列)来模拟递归的行为。使用这种方法时,我们会将要处理的目录放入栈中,然后逐个处理栈中的目录。

下面的示例演示如何不使用递归方式遍历目录树中的文件和文件夹。 此方法使用泛型 Stack 集合类型,此集合类型是一个后进先出 (LIFO) 堆栈。

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(args[0]);
		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);
		}
	}
}

通常,检测每个文件夹以确定应用程序是否有权限打开它是一个很费时的过程。 因此,此代码示例只将此部分操作封装在 try/catch 块中。 你可以修改 catch 块,以便在拒绝访问某个文件夹时,可以尝试提升权限,然后再次访问此文件夹。 一般来说,仅捕获可以处理的、不会将应用程序置于未知状态的异常。

如果必须在内存或磁盘上存储目录树的内容,那么最佳选择是仅存储每个文件的 FullName 属性(类型为string )。 然后可以根据需要使用此字符串创建新的 FileInfo 或 DirectoryInfo 对象,或打开需要进行其他处理的任何文件。

八、总结

本文介绍了如何在C#中循环访问目录树。通过使用System.IO命名空间中的DirectoryInfo和FileInfo类,我们可以轻松地递归遍历文件系统。通过一个示例程序,我们展示了如何列出目录树中的所有文件和文件夹。最后,我们还讨论了异常处理的重要性,以确保程序的健壮性。在编写涉及文件系统操作的代码时,这些技巧和概念将非常有用。

以上就是详解如何在C#中循环访问目录树的详细内容,更多关于C#循环访问目录树的资料请关注脚本之家其它相关文章!

相关文章

  • 基于WPF绘制一个点赞大拇指动画

    基于WPF绘制一个点赞大拇指动画

    这篇文章主要为大家详细介绍了WPF实现绘制一个点赞大拇指动画,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
    2023-02-02
  • C#中常见的数据缓存方式汇总

    C#中常见的数据缓存方式汇总

    在C#开发中,数据缓存是一种优化应用程序性能的常见技术,合理的缓存策略可以减少对数据源的访问次数,提高数据处理速度,从而改善用户体验,下面将详细介绍几种在C#中常见的数据缓存方式,以及相应的实例,需要的朋友可以参考下
    2024-05-05
  • C#客户端程序Visual Studio远程调试的方法详解

    C#客户端程序Visual Studio远程调试的方法详解

    这篇文章主要给大家介绍了关于C#客户端程序Visual Studio远程调试的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • C#判断字符串是否存在字母及字符串中字符的替换实例

    C#判断字符串是否存在字母及字符串中字符的替换实例

    这篇文章主要介绍了C#判断字符串是否存在字母及字符串中字符的替换,实例形式讲述了C#针对字符串的正则操作,需要的朋友可以参考下
    2014-10-10
  • 初学C#所需明白的那些点

    初学C#所需明白的那些点

    这篇文章主要介绍了初学C#所需明白的那些点,以及一些零碎知识点笔记,以供大家学习参考
    2023-03-03
  • C# AutoMapper 使用方法总结

    C# AutoMapper 使用方法总结

    这篇文章主要介绍了C# AutoMapper 使用方法,文中讲解非常细致,代码帮助大家更好的理解学习,感兴趣的朋友可以了解下
    2020-06-06
  • C#重载运算符详解

    C#重载运算符详解

    这篇文章主要介绍了C#重载运算符,是进行C#程序设计中非常重要的一个技巧,需要的朋友可以参考下
    2014-08-08
  • C#动态查询之巧用Expression组合多条件表达式的方法和步骤

    C#动态查询之巧用Expression组合多条件表达式的方法和步骤

    在C#中,可以使用AndAlso和OrElse方法组合两个Expression<Func<T, bool>>类型的表达式,下面通过实例代码给大家分享C#动态查询之巧用Expression组合多条件表达式,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • C#使用DeflateStream解压缩数据文件的方法

    C#使用DeflateStream解压缩数据文件的方法

    这篇文章主要介绍了C#使用DeflateStream解压缩数据文件的方法,较为详细的分析了DeflateStream方法对文件进行压缩及解压缩的步骤与技巧,需要的朋友可以参考下
    2015-04-04
  • c# Linq查询详解

    c# Linq查询详解

    这篇文章主要介绍了c# Linq查询的相关资料,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-04-04

最新评论