首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 遞歸實現文件夾完整拷貝:核心邏輯、命令行編譯與部署實戰

     編輯:關於C語言

.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);
            }
        }
    }
}

二、 命令行工具完整實現 (Program.cs)


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;
            }
        }
    }
}

三、 命令行編譯與部署 (無需 Visual Studio IDE)

  1. 保存上述代碼為 FolderService.cs。
  2. 打開 Developer Command Prompt for VS (或 dotnet CLI)。
  3. .NET Framework (csc.exe):
    
    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
        
  4. .NET Core / .NET 5+ (dotnet CLI):
    
    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
        
  5. 運行測試:
    
    FolderService.exe "D:\SourceData" "E:\BackupData"
        

    csc 編譯
    運行測試

四、 生產環境強化清單

增強點實現方案
長路徑支持 (>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 一鍵方案


// .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)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved