Directory.CreateDirectory 不能替代深拷贝,它仅创建空目录;完整深拷贝需递归处理子目录、文件、权限、时间戳等,推荐使用 .NET 5+ 的 FileSystem.CopyDirectory,但不支持 ACL 和 ADS。

Directory.CreateDirectory 不能替代深拷贝
创建空目录只是第一步,真正要复制整个目录结构(含所有子目录、文件、权限、时间戳),Directory.CreateDirectory 做不到。它只建目录,不处理文件内容、嵌套关系或属性继承。如果你直接遍历 Directory.GetDirectories 和 Directory.GetFiles 后逐个调用 File.Copy,但忽略异常处理、符号链接、只读文件或长路径,大概率会在某一层级失败。
用 FileSystem.CopyDirectory(.NET 5+)最省事
.NET 5 引入了 FileSystem.CopyDirectory,是目前最接近“开箱即用”的深拷贝方案。它默认递归、保留目录结构、跳过只读/隐藏文件时抛出明确异常(可捕获)、支持 overwrite: true/false 控制覆盖行为。
示例:
try
{
FileSystem.CopyDirectory(@"C:\source", @"D:\backup", overwrite: false);
}
catch (IOException ex) when (ex.Message.Contains("The directory is not empty"))
{
// 注意:这个异常可能来自目标目录已存在且 overwrite=false
}
- 不支持复制 NTFS 权限(ACL)和备用数据流(ADS)
- 对符号链接(symlink)默认按内容复制,不是复制链接本身
- 路径长度超过 260 字符时,需确保应用启用 long path 支持(
<EnableLongPath>true</EnableLongPath>)
手动递归实现要注意三个关键点
若需兼容 .NET Framework 或要精细控制(如跳过特定扩展名、记录进度、保留 ACL),就得手写递归。核心逻辑简单,但容易漏掉这些:
- 必须先创建目标子目录,再复制其中文件——顺序反了会报
DirectoryNotFoundException -
File.Copy(src, dst, overwrite)默认不保留最后写入时间;需额外调用File.SetLastWriteTime(dst, File.GetLastWriteTime(src)) - 遇到只读文件时,
File.Copy会失败;得先FileAttributes attrs = File.GetAttributes(src); File.SetAttributes(src, attrs & ~FileAttributes.ReadOnly);再复制,之后视需还原
不要用 Process.Start("xcopy") 或 "robocopy"
虽然 xcopy /E /I /Y 看似快,但它绕过了 .NET 的异常语义,错误码难捕获,输出不可靠,且在容器或受限环境里常被禁用。更严重的是:robocopy 的退出码不是标准 0/非0(比如“仅警告”也返回 1),容易误判失败。纯托管方案可控性高得多,除非你明确需要它的压缩传输或断点续传能力。
深拷贝真正的复杂点不在“怎么递归”,而在于边界情况:空目录是否保留、硬链接如何处理、跨卷复制时的原子性、以及目标磁盘空间不足时的回滚策略——这些都得根据实际场景补全,而不是依赖某个函数自动搞定。










