1. 介绍
想象一下你写了一个程序,用户会往里上传照片。最好不要把照片都堆在一个文件夹里,而是按日期或者用户名创建单独的目录。或者你程序会生成报告:把结果放到一个专门的目录里也是明智的,这个目录需要在运行时创建。程序运行完删除临时文件夹也是好习惯(既干净又给用户省心)。
对目录的操作是很多应用都会遇到的标准任务:从备份到游戏把存档分文件夹存放都有用。面试中也常被问到这类问题,因为这里不仅要知道“创建”或“删除”这两个动作,还要理解在异常情况下这些操作的行为。
目录(或文件夹)本质上是文件系统里存放其他文件和目录的容器。目录构成一棵树(filesystem tree):每个文件夹有父目录(根目录除外),也可以有任意数量的子目录。
2. 如何创建文件夹?静态类 Directory
最简单的创建文件夹的方法是用静态方法 Directory.CreateDirectory。不需要实例化任何对象,只要传入路径:
using System.IO;
// 在当前目录创建文件夹 "Reports"
Directory.CreateDirectory("Reports");
如果该文件夹已经存在,方法不会做任何事也不会抛出错误——可以放心调用 CreateDirectory,不用先判断文件夹是否存在。
我们再试个更复杂的路径,比如创建嵌套文件夹:
Directory.CreateDirectory(@"Data\Photos\2024\June");
这个调用会创建整条目录链,如果某些中间文件夹不存在的话。这个叫做 递归创建 —— Directory.CreateDirectory 会自己处理好所有事情。
重要! 在路径里对 Windows 用双反斜杠 (\\),或用正斜杠 (/)。更好的做法是用我们之前讲过的 Path.Combine。
那么 CreateDirectory 返回什么?
该方法返回一个 DirectoryInfo 对象。如果你想马上对该目录做更多操作,这很方便:
DirectoryInfo reportsDir = Directory.CreateDirectory("Reports");
Console.WriteLine($"已创建文件夹: {reportsDir.FullName}");
怎么知道文件夹是否存在?
在对目录做任何操作前,通常想确认它是否存在。可以用这个静态方法:
bool exists = Directory.Exists("Reports");
if (!exists)
{
Console.WriteLine("文件夹没找到,马上创建!");
Directory.CreateDirectory("Reports");
}
小贴士: 没必要在创建前总做检查:如果文件夹已经存在,CreateDirectory 也不会坏事。但如果你想给用户漂亮的提示或基于存在性做不同逻辑,这种检查就有用。
3. 创建目录:实战场景
把这些知识和我们的教学应用结合一下。假设我们记录用户的条目,并想为每个用户单独存一个文件夹:
// 如果文件顶部还没加 using,就加上 System.IO
using System.IO;
Console.Write("请输入用户名: ");
string userName = Console.ReadLine() ?? "Unknown";
// 拼接用户文件夹的路径
string basePath = "UsersData";
string userPath = Path.Combine(basePath, userName);
// 为用户创建文件夹(如果需要也会创建父目录)
Directory.CreateDirectory(userPath);
Console.WriteLine($"用户文件夹 \"{userName}\" 已准备好: {Path.GetFullPath(userPath)}");
上面例子会创建如下的文件结构(如果之前不存在的话):
UsersData/
└── 用户名/
建议: 当你拼接路径片段时始终使用 Path.Combine,这样代码在 Windows、Linux、Mac 上都能正常工作。
4. 如何删除文件夹?方法 Directory.Delete
删除文件夹几乎和创建一样简单,但有一些细节需要注意。
Directory.Delete("Reports");
如果文件夹存在且为空——会被正常删除。但如果里面有内容,会抛出异常:
System.IO.IOException: "The directory is not empty."
要删除带内容的文件夹怎么办?
有一个带参数的重载——加上 recursive: true:
Directory.Delete("Reports", recursive: true);
注意: 递归删除会不可恢复地清除文件夹内的所有东西。如果路径写错了,可能丢失重要数据。务必再三确认路径!
示例
给程序加一个删除用户文件夹的功能(比如用户注销了):
// 询问是否删除
Console.Write("删除用户文件夹吗? (y/n): ");
string input = Console.ReadLine() ?? "";
if (input.ToLower() == "y")
{
if (Directory.Exists(userPath))
{
// 连同所有内容一起删除
Directory.Delete(userPath, recursive: true);
Console.WriteLine("用户文件夹已删除!");
}
else
{
Console.WriteLine("文件夹已不存在。");
}
}
5. 表格:常用的文件夹操作方法
| 操作 | 方法 | 特点 |
|---|---|---|
| 创建文件夹 | |
递归创建路径上所有文件夹 |
| 检查是否存在 | |
返回 true 或 false |
| 删除空文件夹 | |
如果文件夹非空会抛出错误 |
| 删除包含内容的文件夹 | |
不可恢复地删除内部所有内容 |
| 获取文件列表 | |
返回文件名 |
| 获取子文件夹列表 | |
返回文件夹名 |
6. 不明显的点和常见错误
创建时出错:没有权限或路径不正确
如果你想在系统目录创建(比如 "C:\Windows\System32\SuperApp"),很可能会遇到 UnauthorizedAccessException 或 IOException。
实用建议:
如果操作外部目录(比如用户的 U 盘或网络盘),请务必用 try-catch 来处理错误。
不要盲目信任输入的路径。
try
{
Directory.CreateDirectory(pathFromUser);
}
catch (Exception ex)
{
Console.WriteLine($"无法创建文件夹: {ex.Message}");
}
删除时目录被其他进程占用
如果有人(或你的程序自身)打开了目录里的某个文件并保持着句柄,尝试删除时会得到 IOException —— “无法删除,目录正在被使用”。先关闭目录内的所有文件。
目录不为空,但忘了传 recursive: true
非常常见的问题。如果不传 recursive: true,而目录非空——会抛出异常。
关键操作请使用绝对路径
相对路径(例如 "Reports")是相对于应用程序的当前工作目录的。如果程序从别处启动,文件夹会被创建在你意想不到的地方。确认你的代码从哪里运行,或者直接用完整路径:
string fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyAppData");
Directory.CreateDirectory(fullPath);
GO TO FULL VERSION