파일을 InputStream으로로드하는 다른 방법 다른 것보다 사용하기에 더

차이점은 무엇입니까?

InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName)

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)

InputStream is = this.getClass().getResourceAsStream(fileName)

각각 다른 것보다 사용하기에 더 적합한시기는 언제입니까?

읽으려는 파일이 파일을 읽는 클래스로 클래스 경로에 있습니다. 내 클래스와 파일은 동일한 jar에 있고 EAR 파일로 패키지되어 WebSphere 6.1에 배치됩니다.



답변

fileName당신이 통과 하는 방법에 대한 미묘한 차이점이 있습니다 . 기본적으로, 당신은 2 개 가지 방법이 있습니다 ClassLoader.getResourceAsStream()Class.getResourceAsStream(). 이 두 가지 방법은 리소스를 다르게 찾습니다.

에서 Class.getResourceAsStream(path), 경로는 당신이에서 호출하는 클래스의 패키지 로컬 경로로 해석됩니다. 예를 들어, 호출 String.getResourceAsStream("myfile.txt")은 다음 위치에서 클래스 경로에서 파일을 찾습니다 "java/lang/myfile.txt". 경로가로 시작 /하면 절대 경로로 간주되며 클래스 경로의 루트에서 검색을 시작합니다. 따라서 전화 String.getResourceAsStream("/myfile.txt")는 수업 경로에서 다음 위치를 봅니다 ./myfile.txt.

ClassLoader.getResourceAsStream(path)모든 경로를 절대 경로로 간주합니다. 그래서 호출 String.getClassLoader().getResourceAsStream("myfile.txt")String.getClassLoader().getResourceAsStream("/myfile.txt")것이다 다음 위치에서 클래스 경로에있는 파일 모두보기 : ./myfile.txt.

이 게시물에서 위치를 언급 할 때마다 리소스를로드하는 Class 및 / 또는 ClassLoader에 따라 파일 시스템 자체 또는 해당 jar 파일 내의 위치 일 수 있습니다.

귀하의 경우 Application Server에서 클래스를로드하므로 Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)대신 대신 사용해야 합니다 this.getClass().getClassLoader().getResourceAsStream(fileName). this.getClass().getResourceAsStream()작동합니다.

특정 문제에 대한 자세한 정보는 이 기사 를 읽으십시오 .


Tomcat 7 이하 사용자에게 경고

이 질문에 대한 답변 중 하나는 Tomcat 7에 대한 설명이 올바르지 않은 것 같습니다. 나는 왜 그런지 알기 위해 주위를 둘러 보았습니다.

그래서 Tomcat의 WebAppClassLoader여러 버전에 대한 Tomcat의 소스 코드를 살펴 보았습니다 . findResource(String name)Tomcat 6과 Tomcat 7에서는 구현이 요청 된 자원에 대한 URL을 생성하는 데 가장 큰 책임이 있습니다. 그러나 Tomcat 8에서는 다릅니다.

버전 6 및 7에서는 구현시 자원 이름을 정규화하지 않습니다. 즉,이 버전에서는 Javadoc이 지정하는 것이므로 이벤트 classLoader.getResourceAsStream("/resource.txt")와 동일한 결과를 생성하지 못할 수도 있습니다 classLoader.getResourceAsStream("resource.txt"). [소스 코드]

그러나 버전 8에서는 자원 이름의 절대 버전이 사용되는 것을 보장하기 위해 자원 이름이 정규화됩니다. 따라서 Tomcat 8에서 위에서 설명한 두 호출은 항상 동일한 결과를 반환해야합니다. [소스 코드]

따라서 Tomcat 8 이전 버전을 사용 ClassLoader.getResourceAsStream()하거나 사용할 때는 각별히주의 Class.getResourceAsStream()해야합니다. 또한 class.getResourceAsStream("/resource.txt")실제로 전화를 걸면됩니다 classLoader.getResourceAsStream("resource.txt")(리딩 /은 제거됨).


답변

MyClass.class.getClassLoader().getResourceAsStream(path)코드와 관련된 리소스를로드하는 데 사용 합니다. MyClass.class.getResourceAsStream(path)바로 가기로 사용 하고 클래스 패키지 내에 패키지 된 리소스에 사용하십시오 .

Thread.currentThread().getContextClassLoader().getResourceAsStream(path)호출 코드에 밀접하게 묶이지 않고 클라이언트 코드의 일부인 리소스를 얻는 데 사용 합니다. 스레드 컨텍스트 클래스 로더가 무엇을 가리킬 수 있으므로주의해야합니다.


답변

평범한 Java 7의 평범한 Java는 다른 종속성이 없습니다.

내가 넣어 file.txtc:\temp\내가 넣어 c:\temp\클래스 패스에.

두 통화간에 차이가있는 경우는 한 가지뿐입니다.

class J {

 public static void main(String[] a) {
    // as "absolute"

    // ok   
    System.err.println(J.class.getResourceAsStream("/file.txt") != null);

    // pop            
    System.err.println(J.class.getClassLoader().getResourceAsStream("/file.txt") != null);

    // as relative

    // ok
    System.err.println(J.class.getResourceAsStream("./file.txt") != null);

    // ok
    System.err.println(J.class.getClassLoader().getResourceAsStream("./file.txt") != null);

    // no path

    // ok
    System.err.println(J.class.getResourceAsStream("file.txt") != null);

   // ok
   System.err.println(J.class.getClassLoader().getResourceAsStream("file.txt") != null);
  }
}

답변

이 질문에 대한 답변뿐만 아니라 여기에있는 모든 답변은 “/foo/bar.properties”와 같은 절대 URL을로드하는 것이 class.getResourceAsStream(String)and로 동일하게 처리되었음을 제안합니다 class.getClassLoader().getResourceAsStream(String). 적어도 Tomcat 구성 / 버전 (현재 7.0.40)에는 해당되지 않습니다.

MyClass.class.getResourceAsStream("/foo/bar.properties"); // works!  
MyClass.class.getClassLoader().getResourceAsStream("/foo/bar.properties"); // does NOT work!

죄송합니다, 나는 만족스러운 설명이 없지만 tomcat은 클래스 로더와 함께 더러운 트릭과 그의 검은 마술을하고 차이를 유발한다고 생각합니다. 나는 항상 class.getResourceAsStream(String)과거에 사용 했지만 아무런 문제가 없었습니다.

추신 : 나는 또한 이것을 여기에 게시했습니다 .


답변

성공하지 않고 파일을로드하는 몇 가지 방법을 시도한 후 FileInputStream완벽하게 작동하는을 사용할 수 있음을 기억 했습니다.

InputStream is = new FileInputStream("file.txt");

파일을로 읽는 다른 방법으로 InputStream, 현재 실행중인 폴더에서 파일을 읽습니다.


답변

그것은 작동합니다, 이것을 시도하십시오 :

InputStream in_s1 =   TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");