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

Delphi 實現目錄完整拷貝、刪除與移動的核心代碼詳解

     編輯:Delphi

前言

在 Delphi 開發中,雖然 VCL 提供了 CreateDir、RemoveDir 等基本目錄操作函數,但它們僅能處理空目錄。一旦目錄包含子目錄或文件,這些函數便無能為力。本文將介紹如何利用 Win32 API 結合遞歸算法,實現功能相當於 DOS XCopy、DelTree 和 Move 命令的目錄深度拷貝、刪除與移動操作。

一、 目錄深度拷貝(遞歸實現)

拷貝非空目錄的關鍵在於遞歸遍歷源目錄下的所有文件與子目錄,並在目標路徑重建相同的結構。我們將核心邏輯封裝在輔助函數 DoCopyDir 中,主函數 CopyDir 負責參數校驗與調用。

1.1 遞歸輔助函數:DoCopyDir

該函數使用 FindFirstFile/FindNextFile 遍歷文件,遇到子目錄則遞歸調用自身,遇到文件則直接調用 CopyFile。注意保存並恢復當前工作目錄,避免遞歸過程中路徑混亂。

function DoCopyDir(sDirName: String; sToDirName: String): Boolean;
var
  hFindFile: Cardinal;
  t, tfile: String;
  sCurDir: String[255];
  FindFileData: WIN32_FIND_DATA;
begin
  // 保存當前目錄
  sCurDir := GetCurrentDir;
  ChDir(sDirName);
  hFindFile := FindFirstFile('*.*', FindFileData);
  if hFindFile <> INVALID_HANDLE_VALUE then
  begin
    // 確保目標目錄存在
    if not DirectoryExists(sToDirName) then
      ForceDirectories(sToDirName);
    repeat
      tfile := FindFileData.cFileName;
      // 跳過 "." 和 ".."
      if (tfile = '.') or (tfile = '..') then Continue;

      if (FindFileData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY then
      begin
        // 處理子目錄:遞歸調用
        t := sToDirName + '\' + tfile;
        if not DirectoryExists(t) then ForceDirectories(t);
        if sDirName[Length(sDirName)] <> '\' then
          DoCopyDir(sDirName + '\' + tfile, t)
        else
          DoCopyDir(sDirName + tfile, sToDirName + '\' + tfile);
      end
      else
      begin
        // 處理文件:直接拷貝
        t := sToDirName + '\' + tfile;
        CopyFile(PChar(tfile), PChar(t), True); // True 表示不覆蓋已存在文件
      end;
    until FindNextFile(hFindFile, FindFileData) = False;
    FindClose(hFindFile);
  end
  else
  begin
    ChDir(sCurDir);
    Result := False;
    Exit;
  end;
  // 恢復原始目錄
  ChDir(sCurDir);
  Result := True;
end;

1.2 入口函數:CopyDir

function CopyDir(sDirName: String; sToDirName: String): Boolean;
begin
  if Length(sDirName) <= 0 then Exit;
  Result := DoCopyDir(sDirName, sToDirName);
end;

二、 目錄深度刪除(含空目錄處理)

刪除邏輯與拷貝類似,但需特別處理「空目錄」的刪除。引入標志變量 bEmptyDir 追蹤當前遍歷目錄是否為空,遍歷結束後若為空則刪除該目錄本身。

2.1 遞歸輔助函數:DoRemoveDir

function DoRemoveDir(sDirName: String): Boolean;
var
  hFindFile: Cardinal;
  tfile: String;
  sCurDir: String;
  bEmptyDir: Boolean;
  FindFileData: WIN32_FIND_DATA;
begin
  bEmptyDir := True; // 預設為空目錄
  sCurDir := GetCurrentDir;
  ChDir(sDirName);
  hFindFile := FindFirstFile('*.*', FindFileData);
  if hFindFile <> INVALID_HANDLE_VALUE then
  begin
    repeat
      tfile := FindFileData.cFileName;
      if (tfile = '.') or (tfile = '..') then
      begin
        bEmptyDir := bEmptyDir and True;
        Continue;
      end;
      // 發現文件或子目錄,標記為非空
      bEmptyDir := False;

      if (FindFileData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY then
      begin
        // 遞歸刪除子目錄
        if sDirName[Length(sDirName)] <> '\' then
          DoRemoveDir(sDirName + '\' + tfile)
        else
          DoRemoveDir(sDirName + tfile);
        Result := RemoveDirectory(PChar(tfile));
      end
      else
      begin
        // 刪除文件
        Result := DeleteFile(PChar(tfile));
      end;
      if not Result then Exit; // 遇到失敗即刻退出
    until FindNextFile(hFindFile, FindFileData) = False;
    FindClose(hFindFile);
  end
  else
  begin
    ChDir(sCurDir);
    Result := False;
    Exit;
  end;

  // 若為空目錄,返回上級並刪除自身
  if bEmptyDir then
  begin
    ChDir('..');
    RemoveDirectory(PChar(sDirName));
  end;
  ChDir(sCurDir);
  Result := True;
end;

2.2 入口函數:DeleteDir

function DeleteDir(sDirName: String): Boolean;
begin
  if Length(sDirName) <= 0 then Exit;
  Result := DoRemoveDir(sDirName) and RemoveDir(sDirName); // 最後嘗試刪除根目錄本身
end;

三、 目錄移動

有了拷貝與刪除,移動操作便極為簡單:先拷貝到目標位置,成功後刪除源目錄。

function MoveDir(sDirName: String; sToDirName: String): Boolean;
begin
  Result := False;
  if CopyDir(sDirName, sToDirName) then
    if DeleteDir(sDirName) then // 使用封裝好的 DeleteDir
      Result := True;
end;

總結

本文提供的代碼展示了 Delphi 中通過 Win32 API 實現目錄樹操作的經典模式。核心要點在於:正確管理工作目錄上下文、妥善處理 . 與 .. 特殊目錄、以及利用遞歸實現樹狀結構的深度遍歷。這些函數可直接集成到項目中,滿足大多數文件管理需求。

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