當平台基核執行中且資源外掛程式作用中時,工作區由 IWorkspace 的實例代表,它提供用於內含資源的通訊協定。 IWorkspace 實例代表本端檔案系統中檔案和目錄的相關集成。您可以從 org.eclipse.core.resources 中的資源外掛程式類別來存取工作區。
ResourcesPlugin.getWorkspace();
當資源外掛程式不在執行中時,工作區僅存在於本端檔案系統中,且由使用者透過標 準檔案型工具操作或檢視。讓我們看看解說資源外掛程式 API 時磁碟上工作區的外 觀。
當安裝平台 SDK 後,您將檔案解壓縮到所選擇的目錄中。我們稱這個目錄為 平台根目錄。 這是包含 plugins 目錄的目錄。在平台根目錄內,有一個 workspace 目錄用來保留平台所操作及建立的資源。如果您在 workspace 目錄中查閱,您會看到存在於工作區中每一個專案的個別子目錄 。 在這些子目錄內有每個專案所含的資料夾和檔案。
如果我們範例中的 SDK 安裝在 c:\MySDK 下,則在 c:\MySDK\workspace 目錄內,會看到工作區專案後指名的子目錄 MyWeb 和 MyServlet。這些子目錄稱為專案的內容目錄。 內容目錄是在使用者建立專案時由平台所建立。
在每一個目錄內,我們看到專案內的檔案和資料夾,所呈現的與在工作區資源樹狀結 構中完全一樣。所有檔案名稱都相同,而且無法是從檔案系統或工作區存取,檔案內 容也都一樣。唯一的例外是 .project 檔案,稍後另行說明。
C:\MySDK\workspace (工作區根目錄) .metadata\ (平台 Meta 資料目錄) MyWeb\ (MyWeb 的專案內容目錄) .project index.html images\ logo.gif MyServlet\ (MyServlet 的專案內容目錄) .project src\ main.java bin\ main.class
平台有一個特殊的 .metadata 目錄,用來保存平台內部資訊。 工作區的 .metadata 目錄被視為一個「黑盒子」。有關工作區結 構的重要資訊(例如專案參照或資源內容)儲存於工作區的 Meta 資料部份,而且只 能透過平台 API 由工具存取。這些檔案絕不能利用一般檔案系統 API 來操作 或編輯。
另外,每一個專案有自己的.project 檔案,其中保留關於專案的 meta 資料。基本上這個檔案與專案中找到的資訊 IProjectDescription 相同。
除 .metadata 目錄和 .project 檔案之外,工作區目錄內的資料夾和檔案對其他工具完全 無用。這些檔案和資料夾可由非整合型工具(例如文字編輯器和檔案系統 public 程式)來操作。唯一的問題是使用者在工作台和外部編輯這些檔案時必須小心 。(這和使用者使用兩個獨立式工具編輯檔案一樣。)工作台提供重 新整理作業來使資源的工作區檢視畫面與檔案系統中的實際狀態一致。
資源 API 可讓我們在程式碼中操作這個資源樹狀結構。在此,我們將看到一些程式 碼片段來快速體驗資源 API。資源 API 定義於 org.eclipse.core.resources 的一系列介面中。所有資源類型的一些介面,例如 IProject 、 IFolder 和 IFile 。擴充共用通訊協定定義於 IResource 中。我們也使用 org.eclipse.core.runtime 介面 IPath ,它代表區段式路徑,例如資源或檔案系統路徑。
操作資源非常類似使用 java.io.File 來操作檔案。 API 是以 handles 為基礎。當您使用 API(如 getProject 或 getFolder)時,會傳回 handle 給資源。除非您嘗試以 handle 執行某些操作,否則不保證或需要資源本身存在。如果您預期某資源 存在,可以使用 exists 方法來確定的確如此。
若要從外掛程式導覽工作區,首先必須取得 IWorkspaceRoot ,它代表工作區中資源階層的頂層。
IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
有了工作區根目錄後,就可以存取工作區內的專案了。
IProject myWebProject = myWorkspaceRoot.getProject("MyWeb"); // 如為必要,則開啟 if (myWebProject.exists() && !myWebProject.isOpen()) myWebProject.open(null);
操作專案之前,必須先開啟專案。開啟專案可從磁碟讀取專案結構及建立專案資源樹 狀結構的記憶體中物件表示法。開啟專案是一項明確作業,因為每次開啟專案都會耗 用記憶體來代表內部資源樹狀結構,而且開啟參與不同資源生命週期事件(如建置) 的專案可能會冗長。一般而言,已關閉的專案無法被存取,而即使資源仍在 檔案系統中也不會顯示出來。
注意:在操作資源時,這些資源範例會傳遞 null 參數。 許多資源作業可能相當重要並足以保證進度報告和使用者取消作業。 如果您的程式碼有使用者介面,通常您會傳遞 IProgressMonitor ,它允許資源外掛程式在操作資源時報告進度,也允許使用者在必要時取消作業。 現在,我們只傳遞 null,表示沒有監督進度。
一旦開啟某個專案後,就可以存取它的資料夾和檔案,以及建立其他資料夾和檔案。 在下列範例中,我們根據工作區外的檔案內容建立一個檔案資源。
IFolder imagesFolder = myWebProject.getFolder("images"); if (imagesFolder.exists()) { // 建立新檔案 IFile newLogo = imagesFolder.getFile("newLogo.gif"); FileInputStream fileStream = new FileInputStream( "c:/MyOtherData/newLogo.gif"); newLogo.create(fileStream, false, null); // create closes the file stream, so no worries. }
在上述範例中,第一行取得 images 資料夾的 handle。在執行有關該資料夾 的任何操作前,我們必須檢查資料夾是否存在。同樣地,當我們取得 檔案 newLogo 時,除非在最後一行建立該檔案,否則 handle 不代表實際檔 案。在這個範例中,我們藉由將 logo.gif 的內容移入檔案來建立檔 案。
下一個片段類似上一個片段,不同的是下一個片段根目錄據原始標誌複製 newLogo 檔,而非根據其內容來建立新檔案。
IFile logo = imagesFolder.getFile("logo.gif"); if (logo.exists()) { IPath newLogoPath = new Path("newLogo.gif"); logo.copy(newLogoPath, false, null); IFile newLogo = imagesFolder.getFile("newLogo.gif"); ... }
最後,我們將建立另一個 images 資料夾並將最新建立的檔案移到其中。 因為檔案移動的副作用,我們將檔案重新命名。
... IFolder newImagesFolder = myWebProject.getFolder("newimages"); newImagesFolder.create(false, true, null); IPath renamedPath = newImagesFolder.getFullPath().append("renamedLogo.gif"); newLogo.move(renamedPath, false, null); IFile renamedLogo = newImagesFolder.getFile("renamedLogo.gif");
許多資源 API 方法都包含一個 force Boolean 旗標, 它指定是否更新與本端檔案系統中對應檔不同步的資源。如需詳細資訊, 請參閱 IResource。 您也可以使用 IResource.isSynchronized ,來判定特殊資源是否與檔案系統同步。
在範例資源樹狀結構中,我們假設所有專案內容目錄皆位於平台根目錄(C:\MySDK\workspace) 下的 workspace 目錄中。這是專案的預設配 置。不過,專案的內容目錄可重新對映到檔案系統中任何目錄,可能是另一 個硬碟。
對映與其他專案無關的專案位置功能,可讓使用者將專案內容儲存在專案及專案小組 能夠理解的位置中。專案的內容目錄 "out in the open"。這表示使用者 可利用工作台和外掛程式,或直接使用檔案系統型工具和編輯器來建立、修改及除去 資源。
資源路徑名稱不是完整的檔案系統路徑。資源路徑一律依據專案位置(通常是 workspace 目錄)而定。 若要取得資源的完整檔案系統路徑,您必須使用 IResource.getLocation 來查詢其位置。 然而,您無法使用 IProjectDescription.setLocation 來變更它的位置,因為那個方法是資料結構的簡單 setter。
方便的是,如果您想要取得對應的資源物件給予檔案系統路徑,您可以使用 IWorkspaceRoot.getFileForLocation 或 IWorkspaceRoot.getContainerForLocation。
當使用資源 API 來修改工作區資源樹狀結構時,除了更新資源物件,檔案系統中的 檔案也會變更。資源檔在平台 API 外發生了什麼變更?
除非資源外掛程式有偵測到,否則資源的外部變更不會在工作區和資源物件中反映出 來。 用戶端可使用資源 API 來使工作區和資源物件與本端檔案系統一致,安靜又不需使 用者介入。使用者必可在工作台的資源導覽器檢視畫面中明確地強制重新整理 。
附註:資源 API 中許多方法併入一個 force 參數,它指定如何處理與檔案系 統不同步的資源。每一個方法的 API 參照提供有關此參數的特定資訊。 API 中其他方法允許程式化控制檔案系統重新整理,例如 IResource.refreshLocal(int depth, IProgressMonitor monitor)。有關正 確用法和成本,請參閱 IResource 。