嗨,Scripting Guy!

Hey,Scripting Guy!

歡迎使用全新的 TechNet 專欄,Microsoft Scripting Guy 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

今天的問題:我要如何取得資料夾及其子資料夾中的所有檔案清單?


我要如何取得資料夾及其子資料夾中的所有檔案清單?

嗨,Scripting Guy!我要如何使用指令碼來顯示資料夾中的所有檔案?然後要如何修改指令碼,才能顯示出該資料夾中全部子資料夾的所有檔案?

-- CS

CS,您好。昨天我們示範過的指令碼,能將資料夾中的所有檔案從唯讀變更為可讀寫。我們也曾經承諾,在今天的專欄中,將會解釋如何能在一開始就取得資料夾中所有檔案的清單。您的問題剛好能完美地導入這項解釋。

讓我們從簡單的部份開始進行:單純列出資料夾中所有檔案的指令碼。這段指令碼會回報在資料夾 C:\Scripts 找到的所有檔案的檔案名稱:

Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "C:\Scripts"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
    Wscript.Echo objFile.Name
Next

如您所見,其中的內容非常平淡。我們建立了 FileSystemObject 的例項,然後使用 GetFolder 方法連結到資料夾 C:\Scripts。相當直接了當。假設我們要連結到 Windows 資料夾,只需要據此變更路徑,也就是對 objStartFolder 指派不同的值即可:

objStartFolder = "C:\Windows"

在連結到資料夾以後,我們使用以下命令建立對 Files 屬性的參照:

Set colFiles = objFolder.Files

這能讓我們取得一個集合,由資料夾中能找到的所有檔案組成。(不過,有一點對於您的第二個問題非常重要,此集合並未包含 C:\Scripts 的所有子資料夾內的檔案)。這時候其餘的工作都是輕而易舉的:現在我們可以使用一個 For Each 迴圈來循環通過檔案的集合。而且,如果想要的話,還可以對每個檔案執行一些動作。因為您詢問如何取得資料夾中所有檔案的清單,所以我們只傳回檔案的名稱。不過我們可以辦到並非僅只如此。例如:我們可以回報 DateCreated 屬性或 Size 屬性。如需關於 FileSystemObject 的完整概要及使用方法,請參閱《Microsoft Windows 2000 指令碼指南》中的指令碼執行時期入門 (英文)。

總之,取得資料夾中所有檔案的清單只是小事一樁。取得資料夾中所有檔案,「加上」該資料夾中任何子資夾中的所有檔案清單,就有一些困難了。為了做到這點,您需要使用遞迴的指令碼。我們不會在此解釋遞迴。如需詳細資料,請參閱這個部分的 Microsoft Windows 2000 指令碼指南 (英文)。(沒錯,我們今天還「真是」努力地推銷這本書籍)。基本上,遞迴函式是一種不管需要幾次都能自動自我呼叫的函式。這樣聽起來可能難以理解,不過請用以下的方式來設想。我們以上所示範的指令碼會列出資料夾中的所有檔案,然後停止。不論在資料夾中是否含有子資料夾,指令碼都置之不理。

相較之下,遞迴函式就「會」處理這些:遞迴函式會持續工作,直到完成您的要求,甚至超出您的要求。遞迴函式將列出資料夾中的所有檔案,然後檢查資料夾是否擁有任何子資料夾。假設函式找到子資料夾 A 和 B。在此狀況下,函式便會自我呼叫,並列出在子資料夾 A 中找到的任何檔案。不過如果子資料夾 A 含有子資料夾 C,又該怎麼辦?沒問題:函式會再度呼叫自己,並列出子資料夾 C 中的所有檔案。然後持續進行,直到找不到其他子資料夾為止。此時,函式會從迴圈返回,並開始通過子資料夾 B 進行工作。而且,函式還會盡責地持續工作,直到通過每個子資料夾、子資料夾下的子資料夾、子資料夾下的子資料夾下的子資料夾,等等。也就是直到列出最後一個檔案為止。

這樣聽起來非常複雜可怕,事實上也是如此。不過,幸運的是,VBScript 對您隱藏了大多數的複雜度。嘿,我們又怎麼會對您開這種惡劣的玩笑!請看,以下這段使用遞迴函式 ShowSubFolders 的指令碼,能夠列出資料夾 C:\Scripts 中的所有檔案,以及在 C:\Scripts 下的任何子資料夾中找到的所有檔案。

Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "C:\Scripts"
Set objFolder = objFSO.GetFolder(objStartFolder)
Wscript.Echo objFolder.Path
Set colFiles = objFolder.Files
For Each objFile in colFiles
    Wscript.Echo objFile.Name
Next
Wscript.Echo
ShowSubfolders objFSO.GetFolder(objStartFolder)
Sub ShowSubFolders(Folder)
    For Each Subfolder in Folder.SubFolders
        Wscript.Echo Subfolder.Path
        Set objFolder = objFSO.GetFolder(Subfolder.Path)
        Set colFiles = objFolder.Files
        For Each objFile in colFiles
            Wscript.Echo objFile.Name
        Next
        Wscript.Echo
        ShowSubFolders Subfolder
    Next
End Sub

如您所見,指令碼中的第一段與我們先前看過的指令碼相同 (唯一的例外:這段指令碼傳回資料夾路徑,以便讓我們知道正在查看哪個資料夾)。在顯示過 C:\Scripts 中的所有檔案之後,指令碼呼叫遞迴函式 ShowSubFolders。這個函式便開始細查所有的子資料夾,並回報找到的所有檔案。所有這些「遞迴」作業都會自動進行;您只要放鬆坐著觀看即可。

如果您無法完全瞭解這裡的情況,也請不要憂慮;想要完全瞭解遞迴函式的運作方式,本來就需要花費一些時間。現在,請先直接複製以上的指令碼,以備隨時需要對資料夾及其子資料夾中的所有檔案執行作業時加以使用。


如需詳細資訊

查看嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首