2012-08-03 196 views
10

我試圖刪除一個文件夾及其所有子文件夾遞歸但它根本不工作,所以有人可以檢查代碼並告訴我我在做什麼錯誤?使用Delphi遞歸刪除所有文件和文件夾

我在Windows XP下運行到D7這段代碼

if FindFirst (FolderPath + '\*', faAnyFile, f) = 0 then 
     try    
     repeat 

      if (f.Attr and faDirectory) <> 0 then 
       begin 
        if (f.Name <> '.') and (f.Name <> '..') then 
         begin        
         RemoveDir(FolderPath +'\'+ f.Name); 
         end 
        else 
         begin 
         //Call function recursively... 
         ClearFolder(FolderPath +'\'+ f.Name, mask, recursive); 
         end; 
       end; 

     until (FindNext (f) <> 0); 
     finally 
     SysUtils.FindClose (f) 
     end; 
end; 
+1

如何從JclFileUtils中使用DeleteDirectory? – 2012-08-03 16:12:26

+1

你甚至沒有發佈足夠的代碼給任何人一個真正調試它的機會,我的意思是,我們怎麼知道ClearFolder的功能?技術上來說,下面的答案正在做出假設,因爲你讓人猜測。不過,你的問題很好,而不是重複。好的。其他類似的問題都太具體,你的標題更一般。好。爲你+1! – 2012-08-03 20:34:03

+1

@Warren問題中的代碼是ClearFolder的主體。標準遞歸。 – 2012-08-03 20:45:15

回答

28

而不是做這一切努力自己,我只是用SHFileOperation

uses 
    ShellAPI; 

procedure DeleteDirectory(const DirName: string); 
var 
    FileOp: TSHFileOpStruct; 
begin 
    FillChar(FileOp, SizeOf(FileOp), 0); 
    FileOp.wFunc := FO_DELETE; 
    FileOp.pFrom := PChar(DirName+#0);//double zero-terminated 
    FileOp.fFlags := FOF_SILENT or FOF_NOERRORUI or FOF_NOCONFIRMATION; 
    SHFileOperation(FileOp); 
end; 

對於什麼是值得的,您的代碼存在的問題是它不會撥打DeleteFile。所以目錄永遠不會被清空,RemoveDir的調用失敗等等。在你的代碼中缺少錯誤檢查並沒有真正的幫助,但是添加代碼來刪除文件會使代碼變得體面。您還需要注意遞歸。您必須確保首先刪除所有孩子,然後再刪除父容器。這需要一定的技巧才能得到正確的結果。其基本做法是這樣的:

procedure DeleteDirectory(const Name: string); 
var 
    F: TSearchRec; 
begin 
    if FindFirst(Name + '\*', faAnyFile, F) = 0 then begin 
    try 
     repeat 
     if (F.Attr and faDirectory <> 0) then begin 
      if (F.Name <> '.') and (F.Name <> '..') then begin 
      DeleteDirectory(Name + '\' + F.Name); 
      end; 
     end else begin 
      DeleteFile(Name + '\' + F.Name); 
     end; 
     until FindNext(F) <> 0; 
    finally 
     FindClose(F); 
    end; 
    RemoveDir(Name); 
    end; 
end; 

我省略了錯誤檢查清楚起見,但你應該檢查的DeleteFileRemoveDir的返回值。

+0

事實上,我即將寫出基本相同的答案,但我太慢了。 – 2012-08-03 15:46:25

+0

感謝大衛的幫助。我之所以這麼做是因爲我必須在刪除它們之前對每個已刪除的文件夾執行一些操作......所以我必須在完成我必須完成的任何操作後逐一循環它們做每個文件夾,我必須刪除它... 該API是一個優秀的快速解決方案,我個人更喜歡使用,但由於任務要求,我卡在這裏這個解決方案:( – MChan 2012-08-03 15:47:54

+0

雅,你沒有在這個問題中說,無論如何,我認爲我的更新應該讓你的方式 – 2012-08-03 15:49:02

6
procedure DeleteDir(const DirName: string); 
var 
    Path: string; 
    F: TSearchRec; 

begin 
    Path:= DirName + '\*.*'; 
    if FindFirst(Path, faAnyFile, F) = 0 then begin 
    try 
     repeat 
     if (F.Attr and faDirectory <> 0) then begin 
      if (F.Name <> '.') and (F.Name <> '..') then begin 
      DeleteDir(DirName + '\' + F.Name); 
      end; 
     end 
     else 
      DeleteFile(DirName + '\' + F.Name); 
     until FindNext(F) <> 0; 
    finally 
     FindClose(F); 
    end; 
    end; 
    RemoveDir(DirName); 
end; 
+0

這與我的答案中的代碼有何不同?我能看到的主要原因是RemoveDir不在'如果FindFirst'之外,但是不能有任何區別。那麼爲什麼你用我的答案中基本上完全相同的代碼來產生答案。並且甚至不費心去解釋它是什麼?我很困惑。 – 2012-08-03 16:41:33

+3

@DavidHeffernan - 這是一個社區網站,每個人都可以免費發送問題和答案。我沒有真正看到你最近的更新,只是寫和測試我的代碼。 – kludg 2012-08-03 16:45:24

+1

好的,我明白,代碼與我的代碼基本相同,並且在一段時間後出現,這看起來有點奇怪。 – 2012-08-03 16:53:27

相關問題