차이점은 무엇입니까?
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.txt
에 c:\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");