Java FileInputStream- 파일 개체 참조 방법에 따른 차이점 : 클래스 로더/파일 시스템
-
19-09-2019 - |
문제
사용 중입니다 아파치 포이 Excel 파일에서 일부 데이터를 추출합니다.
POI HSSFWorkbook 클래스를 인스턴스화하려면 입력 스트림이 필요합니다. HSSFWorkbook wb = new HSSFWorkbook(inputStreamX);
INPUTSTREAM 객체를 구성하려고하면 차이점을 찾고 있습니다.
InputStream inputStream = new FileInputStream(new File("/home/xxx/workspace/myproject/test/resources/importTest.xls"));
InputStream inputStream2 = new FileInputStream(getClass().getResource("/importTest.xls").getFile());
InputStream inputStream3 = new ClassPathResource("importTest.xls").getInputStream();
입력 스트림으로 POI 객체를 구성하면 잘 작동합니다.
그러나 inputStream2와 inputStream3은이 예외를 던지고 있습니다
java.io.IOException: Invalid header signature; read -2300849302551019537, expected -2226271756974174256
at org.apache.poi.poifs.storage.HeaderBlockReader.<init>(HeaderBlockReader.java:100)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:84)
이진 파일의 헤더는 다르고 라이브러리는이를 Excel 파일로 인식 할 수 없습니다. 왜 그런지 이해할 수 없습니다.
내가 보는 유일한 차이점은 InputStream2 & 3이 클래스 로더를 사용하여 파일을 찾는 것입니다. (ClassPathResource 스프링 클래스).
파일 경로를 시스템에서 분리하고 싶습니다. 따라서 InputStream2 또는 3과 같은 것을 선호합니다.
왜 이런 일이 일어나고 있는지에 대한 아이디어가 있습니까?
고맙습니다
업데이트:
입력 스트림 및 inputStream2를 디스크로 작성하려고했습니다.
InputStream과 함께 제공되는 Excel 파일은 괜찮습니다. InputStream2에는 실제 콘텐츠를 감싸는 이상한 문자가 포함 된 Excel 파일이 포함되어 있습니다.
Maven은 빌드 중에 어떤 식 으로든 Excel 파일을 손상시키는 것 같습니다.
그래서 기본적으로 클래스 로더로 검색하는 파일입니다 (아래 /home/xxx/workspace/myproject/target/test-classes/importTest.xls
) 괜찮지 않습니다.
아이디어가 있습니까?
해결책
문제는 Maven의 것 같습니다 필터링 옵션.
POM이 이렇게 보인 경우
<testResource>
<directory>${basedir}/src/test/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.sql</include>
<include>**/*.xls</include>
</includes>
<filtering>true</filtering>
</testResource>
XLS 파일에서 필터링 옵션이 true로 설정되면 손상됩니다.
다른 팁
당신은 시도 했습니까? ClassLoader#getResourceAsStream(String)
? 아마도 두 번째 시도와 비슷하게 행동 할 것입니다. Class#getResource(String)
, 후자의 문서에서 언급 한 바와 같이.
여기서 첫 번째 생각은 그러한 파일이 발견되지 않았지만 일관되게 동일한 값을 읽는다면 (-2300849302551019537
) 프로그램을 실행할 때마다 실제로 읽는 파일이 있음을 암시합니다. 초기화 후 진술을 가두십시오 InputStream
디버거의 스트림 인스턴스를 검사하십시오. 기본 파일 이름에 대한 참조를 찾을 수 있어야합니다. 처음에는 더 쉽게 사용하려면 사용해보십시오 ClassLoader#getResources(String)
반환 된 URL의 시퀀스를 검사합니다.