2009-07-27 1 views
3

지정된 클래스 파일의 디렉토리 경로 얻기 : 분명히이클래스 자체에 대한의 .class 파일이 같은 디렉토리에서 일부 구성 파일을 읽으려고 내가 코드에 직면했다

File[] configFiles = new File(
    this.getClass().getResource(".").getPath()).listFiles(new FilenameFilter() { 
     public boolean accept(File dir, String name) { 
      return name.endsWith(".xml"); 
     } 
}); 

을 (아마도, 수지 내부의 코드를 실행하는 경우) 어떤 경우에 작동하지만, 나를 위해, Tomcat을 실행, 단순히, NPE와 함께 실패 getClass().getResource(".") 반환 null 때문이다.

동료는 ".xml"구성 파일 목록을 포함하는 다른 구성 파일을 만들 것을 제안했습니다. 실제로이 파일은 매우 정적으로 유지되므로 실제로 작동합니다. 자바. 주어진을 .class 파일이있는 디렉토리의 경로를 얻기 위해, 보편적으로 작동 일부 좋은 방법, 가있는 경우

는 여전히 궁금하네요?

new File(this.getClass().getResource("MyClass.class").getPath()).getParent() 

을 ... 그러나 이것은 단지/깨끗한 방법입니다 : 나는 당신이 이런 식으로의 .class 파일 자체의 경로에서 그것을 얻을 수있을 것 같아요?

편집 : 명확히하기 위해, 우리는이 MyClass.class 항상 디스크에의 .class 파일에서 읽을 수있는 방법으로 배포 된 응용 프로그램에서 사용하고, 자원에있을 것입니다을 알고 가정 같은 디렉토리.

+0

이 관련 질문을 찾았 http://stackoverflow.com/questions/778187/getting-directory-path-to-class-file-containing-main이 허용 대답은 내가 무엇을 제안 기본적으로 사용 [의 getResource ("MyClass.class"). getPath()] ... 그러나 이것이 유일한 방법인지 아니면 최선의 방법인지 직접 대답하지 않습니다. – Jonik

답변

2

당신은 자신의 디렉토리에있는 디스크의 클래스 파일이 있다고 무엇을 생각하게?

클래스가 될 수있다 : 전체 메모리 jar 파일

에서로드 네트워크 연결

  • 에서로드
  • 에서 만든

    • 당신은 URL이를 만드는 데 사용 얻을 수 있습니다 클래스 자체, 그리고 그 file://로 시작하면 다음 나머지를 얻을 수 ...하지만이 모든 클래스에 대해 작동하지 않습니다. 자원이의 .class 파일과 같은 폴더에있는 경우

  • +0

    네, 제 동료가 대안을 제안 할 때 의미했던 것 같아요. 그러나 클래스가 항상 디스크의 파일에서로드된다는 것을 알면 * 시나리오가 있습니다. - 그렇다면 내가 질문에서 가장 깨끗한 방법으로 제안한 것은 무엇입니까? URL의 시작을 확인하는 팁에 감사드립니다! – Jonik

    +0

    예, 파일 프로토콜에 대한 검사를 추가하면 가장 깨끗한 방법을 찾을 수 있습니다. –

    2

    , 그것은 클래스 경로를 통해 액세스 할 수 있어야합니다 직접 같이 getResourceAsStream를 통해로드 할 수 있습니다. 나는 자바 클래스 로딩이 아니라는 것을 동료에 동의 적절한 (A jarfile가에서 예) "경로"

    +1

    예, 확실합니다. 나는 * 디렉토리 * 경로를 얻는 가장 간단한 방법을 찾고 있었다. (우리가 거기에서 몇 개의 리소스 파일을 읽고 있기 때문에) – Jonik

    +0

    아. ".xml"파일을 미리 이름을 알 필요없이 그 시점의 클래스 경로에서 가져올 수 있습니까? –

    +1

    그래, 그게 주로 요점 이었어. (이 경우에는 기본적으로 이름을 알고 있지만 동적으로 파일을 읽으면 어딘가에 나열하지 않아도됩니다.) – Jonik

    1

    없다 어디 자체가 원격으로로드 또는 장소에서 할 수 있습니다, 이전 클래스를 게시으로

    this.getClass().getResourceAsStream("filename.xml") 
    

    이 사용 사례를 처리하도록 설계되었습니다. Sun Facelets은 URL을 파일에 매핑 할 수 있다고 가정하는 유사한 전략을 사용합니다. 나는 getResource 솔루션이 배포 가정을 고려할 때 가장 깨끗하다고 ​​Jon의 의견에 동의한다. 그것이 유일한 방법이었다 묻는 메시지 때문에, 나는 또한 모두 getClass() 제공 할 수 있습니다. getProtectionDomain를(). getCodeSource을().의 getLocation(), 클래스 로더가 실제로에서 클래스를로드 URL이어야한다 (당신은해야합니다 클래스의 패키지에 하위 디렉토리를 추가하십시오.) 이 전략은 URL- 파일 가정도 동일하기 때문에 이러한 측면에서 더 좋을 수는 없습니다. 나는 다른 일반적인 해결책을 생각할 수 없다. 당신은() 직접 getPath를 사용하지 말아야한다는 것을 의미의 getResource가 인코딩 된 URL을 반환

    참고.특히 공백으로 인해 문제가 발생하지만 환경을 제어 할 경우에는 문제가되지 않을 수 있습니다. 새 파일 (URL.toURI()) 사용을 고려하십시오.

    0

    스프링 프레임 워크의 PathMatchingResourcePatternResolver에 관심이 있으실 것입니다. 코드에서 직접 사용하여 구성 파일을 탐색하거나 here 구현을 찾을 수 있습니다.

    3

    나는이 스레드가 오래되었음을 알고 있지만 Google 검색에서 가장 좋은 결과를 얻었습니다. 여기에 만족할만한 답변이 없었습니다. 내가 작성한 코드는 다음과 같습니다. 물론 디스크에서로드되지 않았을 수도있는주의 사항이 있지만이를 고려하여이 경우 null을 리턴합니다. 이것은 "컨테이너", 즉 클래스의 루트 위치, 항아리 또는 폴더를 찾는 데 유용합니다. 이것은 귀하의 필요에 직접적으로 부합하지 않을 수 있습니다. 그렇지 않은 경우 필요로하는 코드 부분을 자유롭게 추출하십시오.

    /** 
    * Returns the container url for this class. This varies based on whether or 
    * not the class files are in a zip/jar or not, so this method standardizes 
    * that. The method may return null, if the class is a dynamically generated 
    * class (perhaps with asm, or a proxy class) 
    * 
    * @param c The class to find the container for 
    * @return 
    */ 
    public static String GetClassContainer(Class c) { 
        if (c == null) { 
         throw new NullPointerException("The Class passed to this method may not be null"); 
        } 
        try { 
         while(c.isMemberClass() || c.isAnonymousClass()){ 
          c = c.getEnclosingClass(); //Get the actual enclosing file 
         } 
         if (c.getProtectionDomain().getCodeSource() == null) { 
          //This is a proxy or other dynamically generated class, and has no physical container, 
          //so just return null. 
          return null; 
         } 
         String packageRoot; 
         try { 
          //This is the full path to THIS file, but we need to get the package root. 
          String thisClass = c.getResource(c.getSimpleName() + ".class").toString(); 
          packageRoot = StringUtils.replaceLast(thisClass, Pattern.quote(c.getName().replaceAll("\\.", "/") + ".class"), ""); 
          if(packageRoot.endsWith("!/")){ 
           packageRoot = StringUtils.replaceLast(packageRoot, "!/", ""); 
          } 
         } catch (Exception e) { 
          //Hmm, ok, try this then 
          packageRoot = c.getProtectionDomain().getCodeSource().getLocation().toString(); 
         } 
         packageRoot = URLDecoder.decode(packageRoot, "UTF-8"); 
         return packageRoot; 
        } catch (Exception e) { 
         throw new RuntimeException("While interrogating " + c.getName() + ", an unexpected exception was thrown.", e); 
        } 
    } 
    
    관련 문제