자원 및 로컬 파일 시스템

플랫폼이 실행 중이고 자원 플러그인이 활성 상태이면 작업공간이 IWorkspace 인스턴스로 표시되는데, 이 인스턴스는 포함된 자원에 액세스하기 위한 프로토콜을 제공합니다. IWorkspace 인스턴스는 연관된 파일 및 디렉토리 콜렉션을 로컬 파일 시스템에 표시합니다. 자원 플러그인 클래스(org.eclipse.core.resources)에서 작업공간에 액세스할 수 있습니다.

    IWorkspace workspace = ResourcesPlugin.getWorkspace();

자원 플러그인이 실행 중이 아니면, 작업공간은 로컬 파일 시스템에만 존재하고 표준 파일 기반 도구를 통해 사용자가 이를 보거나 조작합니다. 자원 플러그인 API를 설명하면서 디스크에서 작업공간의 모양을 살펴 보도록 합시다.

디스크의 샘플 트리

플랫폼 SDK를 설치했을 때 선택한 디렉토리로 파일의 압축을 풀게 됩니다. 이 디렉토리를 플랫폼 루트 디렉토리라고 합니다. 이 디렉토리는 plugins 디렉토리가 포함된 디렉토리입니다. 플랫폼 루트 디렉토리에는 플랫폼에 의해 작성되고 조작되는 자원을 보유하는 데 사용되는 workspace 디렉토리가 있습니다. workspace 디렉토리를 살펴 보면 작업공간에 있는 각 프로젝트에 대한 독립 서브디렉토리를 확인할 수 있습니다. 이 서브디렉토리에 각 프로젝트에 포함된 파일과 폴더가 있습니다.

이 예에서 SD가 c:\MySDK에 설치되면, c:\MySDK\workspace 디렉토리에 작업공간의 프로젝트( MyWebMyServlet) 이름을 따라 이름 지정된 서브디렉토리가 있습니다. 이 디렉토리를 프로젝트의 컨텐츠 디렉토리라고 합니다. 컨텐츠 디렉토리는 사용자가 프로젝트를 작성할 때 플랫폼에 의해 작성됩니다.

각 디렉토리에 작업공간의 자원 트리에서와 동일한 방법으로 레이아웃된 프로젝트 내의 파일 및 폴더가 있습니다. 모든 파일 이름은 동일하며, 파일 컨텐츠는 파일 시스템에서 액세스하든 작업공간에서 액세스하든 동일합니다. 유일하게 놀라운 것은 .project 파일입니다.

   C:\MySDK\workspace  (workspace root)
      .metadata\ (platform metadata directory
      MyWeb\ (project content directory for MyWeb)
	 .project
         index.html
         images\
            logo.png
      MyServlet\ (project content directory for MyServlet)
	 .project
         src\
            main.java
         bin\
            main.class

플랫폼에는 플랫폼 내부 정보를 보유하기 위한 특수 .metadata 디렉토리가 있습니다. 작업공간의 .metadata 디렉토리는 "블랙 박스"로 간주됩니다. 작업공간 구조에 대한 중요한 정보(예: 프로젝트 참조사항 또는 자원 특성)가 작업공간의 메타데이터 부분에 저장되며, 플랫폼 API를 통해 도구에 의해서만 정보에 액세스해야 합니다.  일반 파일 시스템 API를 사용하여 이 파일을 편집하거나 조작해서는 안됩니다.

그리고 모든 프로젝트에는 프로젝트에 대한 메타데이터가 보관되는 고유한 .project 파일이 있습니다. 이 파일은 기본적으로 프로젝트의 IProjectDescription에 있는 정보와 디스크상 동등한 정보입니다.  

.metadata 디렉토리를 제외하고, 작업공간 디렉토리의 폴더 및 .project 파일은 다른 도구로 사용할 수 있습니다. 이 디렉토리의 파일 및 폴더는 통합되지 않은 도구(예: 문서 편집기 및 파일 시스템 유틸리티)가 조작할 수 있습니다. 유일한 문제점은 사용자가 Workbench에서 이 파일을 편집하거나 외부적으로 파일을 편집할 때 주의해야 한다는 것입니다. 이것은 사용자가 두 개의 독립형 도구를 사용하여 파일을 편집하는 경우와 다르지 않습니다. Workbench는 자원에 대한 작업공간 보기를 파일 시스템의 실제 상태와 일치시키기 위해 새로 고치기 조작을 제공하며, 파일 시스템의 상태를 기반으로 주기적으로 작업공간을 새로 고칩니다.

코드의 샘플 트리

자원 API를 사용하면 이 자원 트리를 코드로 조작할 수 있습니다. 자원 API를 간략히 살펴 보기 위해 몇 가지 코드 스니펫을 살펴 보도록 하겠습니다. 자원 API는 org.eclipse.core.resources에 일련의 인터페이스로 정의됩니다. 자원 유형(예: IProject, IFolderIFile) 모두에 대해 인터페이스가 있습니다. 광범위한 공통 프로토콜은 IResource에 정의됩니다. 자원 또는 파일 시스템 경로 같은 세그먼트화된 경로를 표시하는 org.eclipse.core.runtime 인터페이스 IPath도 사용합니다.

자원 조작은 java.io.File을 사용하여 파일을 조작하는 것과 매우 비슷합니다. API는 핸들을 기반으로 합니다. getProject 또는 getFolder와 같은 API를 사용할 때 핸들이 자원으로 리턴됩니다.  핸들로 무엇인가 수행하려고 시도할 때까지 자원이 존재한다는 보장이나 요구사항은 없습니다. 자원이 존재하는 것으로 예상되면 exist 메소드를 사용하여 존재 여부를 확인할 수 있습니다.  

플러그인에서 작업공간을 탐색하려면 작업공간에서 자원 계층 구조 맨 위를 표시하는 IWorkspaceRoot를 먼저 얻어야 합니다.

IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

작업공간 루트가 있으면, 작업공간의 프로젝트에 액세스할 수 있습니다.

   IProject myWebProject = myWorkspaceRoot.getProject("MyWeb");
// open if necessary
   if (myWebProject.exists() && !myWebProject.isOpen())
      myWebProject.open(null);

프로젝트를 조작하기 전에 먼저 프로젝트를 열어야 합니다. 프로젝트를 열면 디스크에서 프로젝트 구조를 읽어 프로젝트의 자원 트리에 대한 내부 메모리 오브젝트 표시를 작성합니다. 프로젝트 열기는 열린 각 프로젝트가 내부적으로 자원 트리를 표시하기 위해 메모리를 사용하고 열린 프로젝트가 여러 자원 라이프 사이클 이벤트(예: 빌드)에 참여하는 명시적인 조작입니다. 일반적으로 처리완료된 프로젝트에는 액세스할 수 없으며, 자원이 파일 시스템에 계속 있더라도 처리완료된 프로젝트는 빈 상태로 표시됩니다.

이 자원 예제 중 다수가 자원을 조작할 때 매개변수를 전달한다는 사실을 알 수 있습니다. 다수의 자원 조작은 진행 보고 및 사용자 취소 등이 필요할 수 있는 복잡한 작업입니다. 코드에 사용자 인터페이스가 있는 경우, 일반적으로 자원이 조작될 때 자원 플러그인이 진행을 보고할 수 있도록 하고 사용자가 원하면 조작을 취소할 수 있도록 하는 IProgressMonitor를 전달합니다.  지금은 진행 모니터가 없음을 표시하는 만 전달합니다.

프로젝트가 열려 있으면 폴더 및 파일에 액세스할 수 있으며, 폴더 및 파일을 추가로 작성할 수도 있습니다. 다음 예제에서는 작업공간 밖에 위치한 파일 컨텐츠에서 파일 자원을 작성합니다.

   IFolder imagesFolder = myWebProject.getFolder("images");
if (imagesFolder.exists()) {
      // create a new file
      IFile newLogo = imagesFolder.getFile("newLogo.png");
      FileInputStream fileStream = new FileInputStream(
         "c:/MyOtherData/newLogo.png");
      newLogo.create(fileStream, false, null);
      // create closes the file stream, so no worries.   
   }

위의 예제에서 첫 번째 행은 이미지 폴더에 대한 핸들을 얻습니다.  폴더에 대해 관심이 있는 작업을 수행하기 전에 폴더 존재 여부를 확인해야 합니다.  마찬가지로, 파일 newLogo를 얻을 때, 마지막 행에서 파일을 작성할 때까지 핸들이 실제 파일을 표시하지 않습니다.  이 예제에서는 logo.png의 컨텐츠로 채워서 파일을 작성합니다.

다음 스니펫은 컨텐츠에서 새 파일을 작성하지 않고 원래 로고에서 newLogo 파일을 복사한다는 것을 제외하면 이전 스니펫과 유사합니다.

   IFile logo = imagesFolder.getFile("logo.png");
   if (logo.exists()) {
      IPath newLogoPath = new Path("newLogo.png");
      logo.copy(newLogoPath, false, null);
      IFile newLogo = imagesFolder.getFile("newLogo.png");
      ...
   }

마지막으로, 또다른 이미지 폴더를 작성하여 새로 작성한 파일을 그 폴더로 이동합니다. 파일 이름을 바꿔 새로 작성한 파일이 이전 파일을 덮어쓰지 않도록 합니다.

   ...
   IFolder newImagesFolder = myWebProject.getFolder("newimages");
   newImagesFolder.create(false, true, null);
   IPath renamedPath = newImagesFolder.getFullPath().append("renamedLogo.png");
   newLogo.move(renamedPath, false, null);
   IFile renamedLogo = newImagesFolder.getFile("renamedLogo.png");

다수의 자원 API 메소드에는 로컬 파일 시스템의 해당 파일과 동기화되지 않은 자원의 갱신 여부를 지정하는 force 부울 플래그가 있습니다. 자세한 정보는 IResource를 참조하십시오. IResource.isSynchronized를 사용하여 특정 자원이 파일 시스템과 동기화되었는지 확인할 수도 있습니다.

자원을 디스크 위치에 맵핑

샘플 자원 트리에서, 모든 프로젝트 컨텐츠 디렉토리가 플랫폼 루트 디렉토리(C:\MySDK\workspace) 아래의 workspace 디렉토리에 있다고 가정했습니다. 이것은 프로젝트의 기본 구성입니다.  그러나 프로젝트의 컨텐츠 디렉토리를 파일 시스템(다른 디스크 드라이브)의 임의의 디렉토리에 다시 맵핑할 수 있습니다.

다른 프로젝트에 독립적으로 프로젝트 위치를 맵핑하는 기능을 사용하면 사용자가 프로젝트 컨텐츠를 프로젝트 및 프로젝트 팀에 적당한 위치에 저장할 수 있습니다. 프로젝트의 컨텐츠 디렉토리는 "개방적"이어야 합니다. 이는 사용자가 Workbench와 플러그인을 사용하여 또는 파일 시스템 기반의 도구와 편집기를 사용하여 간접적으로 자원을 작성, 수정, 삭제할 수 있음을 의미합니다.

자원 경로 이름은 완전한 파일 시스템 경로가 아닙니다. 자원 경로는 항상 프로젝트의 위치에 딸 결정됩니다(대개 workspace 디렉토리). 자원에 대한 전체 파일 시스템 경로를 얻으려면 IResource.getLocation을 사용하여 해당 위치를 조회해야 합니다.  그러나 해당 메소드는 데이터 구조의 단순한 Setter에 불과하므로 해당 위치를 변경하기 위해 IProjectDescription.setLocation 을 사용할 수 없습니다.   

반대로 파일 시스템 경로가 제공된 해당하는 자원 오브젝트를 가져오려면 IWorkspaceRoot.getFileForLocation 또는 IWorkspaceRoot.getContainerForLocation를 사용할 수 있습니다.

자원 API 및 파일 시스템

자원 API를 사용하여 작업공간의 자원 트리를 수정할 경우, 파일이 파일 시스템에서 변경되며 자원 오브젝트가 갱신됩니다. 플랫폼 API 밖에서 발생하는 자원 파일에 대한 변경사항은 어떻게 될까요?

자원에 대한 외부 변경사항은 자원 플러그인에 의해 발견될 때까지 작업공간 및 자원 오브젝트에 반영되지 않습니다. 또한 자원 플러그인은 파일 시스템에 작성된 외부 변경사항을 발견하기 위해 각 특정 기본 운영 체제에 적절한 메커니즘을 사용합니다. 또한 클라이언트는 자원 API를 사용하여 작업공간 및 자원 오브젝트를 사용자의 개입 없이 로컬 파일 시스템과 일치시킬 수 있습니다. 사용자는 Workbench의 자원 네비게이터 보기에서 명시적으로 새로 고치기를 강제 실행할 수도 있습니다.

자원 API에서 다수의 메소드에 파일 시스템과 동기화되지 않은 자원을 처리하는 방법을 지정하는 force 매개변수가 포함되어 있습니다. 각 메소드에 대한 API 참조는 이 매개변수에 대한 특정 정보를 제공합니다. API에서 기타 메소드는 파일 시스템 새로 고치기에 대한 프로그램 제어(예: IResource.refreshLocal(int depth, IProgressMonitor monitor)를 허용합니다. 올바른 사용법과 문제점에 대한 정보는 IResource를 참조하십시오.

외부 파일 시스템의 상태를 기반으로 작업공간을 주기적으로 새로 고치는 고유 메커니즘을 제공하려는 플러그인은 org.eclipse.core.resources.refreshProviders 확장점을 사용하여 이를 수행할 수 있습니다. 자세한 정보는 새로 고치기 제공자를 참조하십시오.