getResourceAsStream () 대 FileInputStream webapp에 파일을로드하려고했지만을 FileNotFound사용할 때

webapp에 파일을로드하려고했지만을 FileNotFound사용할 때 예외 가 발생했습니다 FileInputStream. 그러나 동일한 경로를 사용하여 파일을로드 할 수있었습니다 getResourceAsStream(). 두 방법의 차이점은 무엇이며 다른 하나는 작동하지 않는 이유는 무엇입니까?



답변

java.io.File및 배우자들은 로컬 디스크 파일 시스템에 작용한다. 문제의 근본 원인은 상대 경로 java.io가 현재 작업 디렉토리에 의존하기 때문입니다. 즉, JVM (웹 서버의 경우)이 시작된 디렉토리입니다. 예를 들어 이것은 C:\Tomcat\bin완전히 다르거 나 전혀 달라도되지만 예상치 못한 결과 일 C:\Tomcat\webapps\contextname 수도 있습니다. 일반적인 이클립스 프로젝트에서는 그렇습니다 C:\Eclipse\workspace\projectname. 다음과 같은 방법으로 현재 작업 디렉토리에 대해 배울 수 있습니다.

System.out.println(new File(".").getAbsolutePath());

그러나 작업 디렉토리는 프로그래밍 방식으로 제어 할 수 없습니다. 당신은 정말 사용을 선호한다 절대 에 경로를 File대신 상대 경로의 API. 예 :C:\full\path\to\file.ext .

Java (웹) 응용 프로그램의 절대 경로를 하드 코딩하거나 추측하고 싶지 않습니다. 이는 이식성 문제 일뿐입니다 (즉, 시스템 X에서는 실행되지만 시스템 Y에서는 실행되지 않음). 일반적인 방법은 이러한 종류의 리소스를 classpath 에 배치하거나 클래스 경로에 전체 경로를 추가하는 것입니다 (Eclipse와 같은 IDE에서 각각 src폴더 및 “빌드 경로”). 이 방법으로 ClassLoaderby ClassLoader#getResource()또는의 도움으로 그들을 잡을 수 있습니다 ClassLoader#getResourceAsStream(). 우연의 일치로 클래스 경로의 “루트”를 기준으로 파일을 찾을 수 있습니다. 웹 응용 프로그램 (또는 여러 클래스 로더를 사용하는 다른 응용 프로그램)에서는에서 ClassLoader반환 한대로 사용하는 것이 좋습니다Thread.currentThread().getContextClassLoader() 컨텍스트를 “외부”로 볼 수 있도록 대해 .

webapps의 또 다른 대안은 ServletContext#getResource()및 대응 ServletContext#getResourceAsStream()입니다. web폴더를 포함하여 webapp 프로젝트 의 공용 폴더에있는 파일에 액세스 할 수 있습니다 /WEB-INF. 은 ServletContext상속에 의해 서블릿에서 사용할 수 있습니다getServletContext() 방법, 당신은있는 그대로 호출 할 수 있습니다.

또한보십시오:


답변

getResourceAsStream 이미 배운대로 웹 앱에 올바른 방법입니다.

웹 앱을 WAR로 패키지화하면 파일 시스템에서 읽을 수 없기 때문입니다. 이것은 웹앱을 패키징하는 올바른 방법입니다. 절대 파일 경로 또는 앱 서버가 설치된 위치에 의존하지 않기 때문에 이식성이 뛰어납니다.


답변

FileInputStream은 작업 디렉토리 와 관련하여 생성자에 전달하는 파일 경로를로드합니다. Java 프로세스 를 . 일반적으로 웹 컨테이너에서는 bin폴더 와 유사 합니다.

getResourceAsStream()응용 프로그램의 classpath에서 상대적인 파일 경로를로드합니다 .


답변

FileInputStream클래스는 기본 파일 시스템과 직접 작동합니다. 해당 파일이 실제로 존재하지 않으면 파일을 열 수 없습니다. 이 getResourceAsStream()방법은 다르게 작동합니다. ClassLoader호출 된 클래스를 사용하여 자원을 찾아로드하려고 시도합니다 . 예를 들어 jar파일에 포함 된 리소스를 찾을 수 있습니다.


답변

classname.getResourceAsStream ()은 classname의 클래스 로더를 통해 파일을로드합니다. 클래스가 jar 파일에서 온 경우 자원이로드 될 위치입니다.

FileInputStream은 파일 시스템에서 파일을 읽는 데 사용됩니다.


답변

여기에서는 File Read (java.io) 및 Resource Read (ClassLoader.getResourceAsStream ())로 표시하여 사용법을 분리하여 여기에 있습니다.

파일 읽기-1
. 로컬 파일 시스템에서 작동합니다. 2. 현재 JVM 시작 디렉토리에서 요청한 파일을 루트로 찾으려고 시도합니다. / dev / files 또는 C : \ Data와 같이 미리 결정된 위치에서 처리하기 위해 파일을 사용할 때 이상적입니다.

리소스 읽기-1
. 클래스 경로 2에서 작동합니다. 현재 또는 상위 클래스 로더 클래스 경로에서 파일 / 자원을 찾으려고 시도합니다. 3. war 또는 jar와 같은 패키지 파일에서 파일을로드 할 때 이상적입니다.


답변