.NET Framework 早期缺乏 Directory.Copy 一鍵拷貝目錄的 API。本文提供一個**生產級遞歸拷貝實現**,涵蓋參數校驗、異常處理、命令行編譯部署全流程,適配 .NET Framework 2.0+ / .NET Core / .NET 5+。
public static class DirectoryEx {
///
/// 遞歸拷貝目錄 (含子目錄、文件、屬性)
///
/// 源目錄
/// 目標目錄
/// 覆蓋同名文件
/// 遞歸子目錄
/// 源目錄不存在
/// IO 錯誤
/// 權限不足
public static void Copy(string sourceDir, string destDir,
bool overwrite = true, bool copySubDirs = true) {
// 1. 校驗源目錄
var src = new DirectoryInfo(sourceDir);
if (!src.Exists) throw new DirectoryNotFoundException($"源目錄不存在: {sourceDir}");
// 2. 創建目標目錄 (含屬性)
Directory.CreateDirectory(destDir);
// 可選:複製目錄屬性 (創建時間、訪問控制等)
// File.SetCreationTime(destDir, src.CreationTime);
// 3. 拷貝當前層級文件
foreach (FileInfo file in src.GetFiles()) {
string destPath = Path.Combine(destDir, file.Name);
file.CopyTo(destPath, overwrite);
// 可選:保留文件屬性
// File.SetAttributes(destPath, file.Attributes);
// File.SetCreationTime(destPath, file.CreationTime);
// File.SetLastWriteTime(destPath, file.LastWriteTime);
}
// 4. 遞歸子目錄
if (copySubDirs) {
foreach (DirectoryInfo subDir in src.GetDirectories()) {
string destSubDir = Path.Combine(destDir, subDir.Name);
Copy(subDir.FullName, destSubDir, overwrite, true);
}
}
}
}
using System;
using System.IO;
namespace FolderService {
class Program {
static int Main(string[] args) {
if (args.Length != 2) {
Console.Error.WriteLine("用法: FolderService.exe <源目錄> <目標目錄>");
Console.Error.WriteLine("示例: FolderService.exe D:\\Data E:\\Backup");
return 1; // 非零退出碼
}
string src = args[0];
string dest = args[1];
try {
Console.WriteLine($"開始拷貝: {src} → {dest}");
DirectoryEx.Copy(src, dest, overwrite: true, copySubDirs: true);
Console.WriteLine("拷貝完成。");
return 0;
}
catch (Exception ex) {
Console.Error.WriteLine($"拷貝失敗: {ex.Message}");
// 可選:記錄完整堆疊到日誌文件
return 2;
}
}
}
}
FolderService.cs。dotnet CLI)。
csc /out:FolderService.exe /target:exe FolderService.cs
# 或針對 .NET 4.x
csc /out:FolderService.exe /target:exe /langversion:latest /r:System.IO.FileSystem.dll FolderService.cs
dotnet new console -n FolderService -o .
# 替換 Program.cs 為上述代碼
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o ./publish
# 生成單文件可執行文件 ./publish/FolderService.exe
FolderService.exe "D:\SourceData" "E:\BackupData"


| 增強點 | 實現方案 |
|---|---|
| 長路徑支持 (>260字符) | 前綴 \\?\ 或 .NET Core 3.0+ 默認支持 |
| 符號鏈接/重解析點 | FileInfo.LinkTarget 檢測,決定複製鏈接還是目標 |
| 權限/ACL 保留 | FileSecurity/AccessControl 複製 GetAccessControl/SetAccessControl |
| 進度報告/取消 | IProgress<long> + CancellationToken |
| 大文件流式複製 | FileStream.CopyToAsync 避免大文件佔用內存 |
| 錯誤重試/跳過 | 策略模式封裝 CopyFileAction (Retry/Skip/Abort) |
| 日誌/審計 | Serilog / Microsoft.Extensions.Logging |
// .NET 5+ / .NET Core 3.0+ (實際為內部遞歸實現)
Directory.Copy(sourceDir, destDir, recursive: true); // 尚未官方提供,社區常用上述 DirectoryEx
// 第三方庫: Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory
// 需引用 Microsoft.VisualBasic.dll
using Microsoft.VisualBasic.FileIO;
FileSystem.CopyDirectory(src, dest, UIOption.AllDialogs, UICancelOption.ThrowException);
遞歸拷貝目錄看似簡單,**邊界條件決定質量**:權限、符號鏈接、長路徑、並發、取消、進度。造輪子練手可,生產建議用經過千萬行測試的庫 (如
AlphaFS、System.IO.Abstractions) 或封裝系統 API (SHFileOperation/IFileOperation)。