C# 循环访问目录树详解与示例

news2024/11/14 20:54:05

文章目录

  • 一、目录树遍历的概念
  • 二、使用System.IO命名空间
  • 三、DirectoryInfo和FileInfo类
  • 四、递归遍历目录树
  • 五、示例:列出目录树中的所有文件和文件夹
  • 六、异常处理
  • 七、迭代方法
  • 八、总结

在这里插入图片描述


在C#中,访问文件系统是常见的需求之一。有时我们需要遍历目录树以执行某些操作,例如搜索文件、计算目录大小或执行批量处理。本文将详细介绍如何在C#中循环访问目录树,并提供一个完整的示例。

一、目录树遍历的概念

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

二、使用System.IO命名空间

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

using System.IO;

三、DirectoryInfo和FileInfo类

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

  1. DirectoryInfo:提供创建、移动、删除目录等方法。
  2. 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类,我们可以轻松地递归遍历文件系统。通过一个示例程序,我们展示了如何列出目录树中的所有文件和文件夹。最后,我们还讨论了异常处理的重要性,以确保程序的健壮性。在编写涉及文件系统操作的代码时,这些技巧和概念将非常有用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2074411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式开发技术进步带来新机遇

嵌入式开发作为信息技术领域的重要分支&#xff0c;随着科技的不断进步&#xff0c;正迎来新的机遇。本文将从人工智能、物联网、边缘计算等方面探讨嵌入式开发技术的进步如何带来新的发展机遇&#xff0c;并展望未来的发展趋势。 一、引言 嵌入式系统是一种特殊的计算机系统&…

unreal engine5中character角色和怪物交互时发生穿模

UE5系列文章目录 文章目录 UE5系列文章目录前言一、原因定位二、解决方法 前言 在 Unreal Engine 5 中&#xff0c;角色“穿模”通常指的是角色模型与其他物体&#xff08;如墙壁、地面或其他对象&#xff09;发生不正确的穿透或重叠现象。这可能是由多种原因造成的&#xff0…

C++ | Leetcode C++题解之第372题超级次方

题目&#xff1a; 题解&#xff1a; class Solution {const int MOD 1337;int pow(int x, int n) {int res 1;while (n) {if (n % 2) {res (long) res * x % MOD;}x (long) x * x % MOD;n / 2;}return res;}public:int superPow(int a, vector<int> &b) {int an…

C# 泛型类型的约束详解与示例

文章目录 一、泛型约束概述二、泛型约束详解与示例1. 类约束2. 接口约束3. 引用类型约束4. 值类型约束5. 无参数构造函数约束6、多重约束7、默认构造函数约束8、基类和接口的组合约束 三、总结 在C#编程语言中&#xff0c;泛型是一种非常强大的特性&#xff0c;它允许我们编写可…

NetSuite 2024.2 学习笔记

NetSuite一年两次的发版&#xff0c;每次都会带来一些新的东西。这对于顾问来说&#xff0c;应该成为必修课。 每个版本发版内容的学习时长&#xff0c;大约在20小时左右。包括&#xff1a; •Release Notes通读 •Release Preview环境申请 •热点功能验证 •New Release学习笔…

vue中video视频路径改变,dom不更新问题

效果展示 视频切换前 视频切换后 完整代码 <template><!-- 设置v-if只在路径有值时&#xff0c;标签才存在 --><video v-if"state.videoSrc ! null" controls><source :src"state.videoSrc" type"video/mp4"></…

Java | Leetcode Java题解之第372题超级次方

题目&#xff1a; 题解&#xff1a; class Solution {static final int MOD 1337;public int superPow(int a, int[] b) {int ans 1;for (int e : b) {ans (int) ((long) pow(ans, 10) * pow(a, e) % MOD);}return ans;}public int pow(int x, int n) {int res 1;while (n…

Pytorch实现CIFAR10训练模型

文章目录 简述模型结构模型参数、优化器、损失函数参数初始化优化器损失函数 模型训练、测试集预测、模型保存、日志记录训练测试集测试模型保存模型训练完整代码 tensorboard训练可视化结果train_loss测试准确率测试集loss 模型应用模型独立应用代码api.py预测结果 简述 使用…

leetcode1232一点小问题

解法 a x 2 − x 1 y 2 − y 1 &#xff0c; b y 1 − a x 1 a\frac{x_{2}-x_{1}}{y_{2}-y_{1}} &#xff0c;by_{1}-ax_{1} ay2​−y1​x2​−x1​​&#xff0c;by1​−ax1​ d y n − y n − 1 x n − x n − 1 d\frac{y_{n}-y_{n-1}}{x_{n}-x_{n-1}} dxn​−xn−1​yn​…

【初阶数据结构】链表题的证明

环形链表题目方法的证明 证明1&#xff1a;为什么快指针每次⾛两步&#xff0c;慢指针⾛⼀步可以相遇&#xff0c;有没有可能遇不上&#xff0c;请推理证明&#xff01; 证明二&#xff1a;为什么相遇点&#xff08;meet&#xff09;和头结点&#xff08;head&#xff09;到入环…

sql server导入mysql,使用工具SQLyog

概述 需要将sql server的数据导入到mysql中&#xff0c;由于2种数据库存在各种差异&#xff0c;比如表字段类型就有很多不同&#xff0c;因此需要工具来实现。 这里使用SQLyog来实现。 SQLyog安装 安装过程参考文档&#xff1a;https://blog.csdn.net/Sunshine_liang1/article/…

USART之串口发送+接收应用案例

文章目录 前言一、电路接线图二、应用案例代码三、应用案例分析3.1 USART模块初始化3.1.1 RCC开启时钟3.1.2 GPIO初始化3.1.3 配置USART3.1.4 开启中断、配置NVIC3.1.5 开启USART 3.2 USART串口收发模块3.2.1 Serial_SendByte&#xff08;发送一个字节数据&#xff09;3.2.2 US…

JVM对象创建和内存分配机制深度解析

一、对象创建方式 1、new关键字 这是最常见的创建对象的方式。通过调用类的构造方法&#xff08;constructor&#xff09;来创建对象。如&#xff1a;MyClass obj new MyClass()。这种方式会触发类的加载、链接、初始化过程&#xff08;如果类还未被加载过的话&#xff09;&…

递归搜索与回溯专题篇一

目录 组合 目标和 组合总和 字母大小全排列 组合 题目 思路 解决这道题利用DFS&#xff0c;决策树是怎样的&#xff1f;以n4&#xff0c;k3为例&#xff1a; 因为每个数只用到一次&#xff0c;因此需要剪枝&#xff0c;将出现重复数字的枝剪掉&#xff0c;因为组合中元素的…

Vue中的this.$emit()方法详解【父子组件传值常用】

​在Vue中&#xff0c;this.$emit()方法用于触发自定义事件。它是Vue实例的一个方法&#xff0c;可以在组件内部使用。 使用this.$emit()方法&#xff0c;你可以向父组件发送自定义事件&#xff0c;并传递数据给父组件。父组件可以通过监听这个自定义事件来执行相应的逻辑。 …

【PyQt6 应用程序】QTDesigner生成ui文件转成py源码并执行

要使用Qt Designer设计的UI界面生成Python代码并执行需要遵循几个步骤。确保已经安装了PyQt6和Qt Designer。Qt Designer是一个强大的工具,允许通过拖放组件来设计GUI界面,而不需要手写所有的代码。安装PyQt6时 Qt Designer通常会一起被安装。 文章目录 使用Qt Designer设计U…

米联客FDMA3.2源码分析以及控制BRAM、DDR3读写验证

文章目录 一、FDMA简介二、读写操作时序2.1 写时序2.2 读时序 三、FDMA源码分析四、源码仿真验证4.1 FDMA控制代码4.2 系统框图4.3 仿真结果4.3.1 写通道4.3.2 读通道 五、使用FDMA控制BRAM读写测试5.1 系统框图5.2 读写数据控制模块5.3 仿真结果5.4 下板验证 六、使用FDMA控制…

快讯 | 美军500天AI计划启动,“破解AI“与“反AI“策略亮相

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

VBA之正则表达式(46)-- 解析业务逻辑公式

实例需求&#xff1a;某业务系统的逻辑公式如下所示&#xff08;单行文本&#xff09;&#xff0c;保存在活动工作表的A1单元格中。 "DSO_90Day"->"FA_NoFunc"->"FCCS_No Intercompany"->"FCCS_Data Input"->"FCCS_…

<数据集>非洲动物识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1504张 标注数量(xml文件个数)&#xff1a;1504 标注数量(txt文件个数)&#xff1a;1504 标注类别数&#xff1a;4 标注类别名称&#xff1a;[buffalo, elephant, rhino, zebra] 序号类别名称图片数框数1buffalo3…