java FileInputStream - diferenças com base em como o objeto de arquivo é referenciado: classloader / filesystem
-
19-09-2019 - |
Pergunta
Eu estou usando Apache POI para extrair alguns dados de um arquivo excel.
Eu preciso de um InputStream para instanciar a classe POI HSSFWorkbook
HSSFWorkbook wb = new HSSFWorkbook(inputStreamX);
Eu estou achando diferenças se eu tentar construir o objeto InputStream como
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();
Se eu construir o objeto POI com inputStream ele funciona bem.
Mas inputStream2 e inputStream3 está jogando essa exceção
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)
Parece que o cabeçalho do arquivo binário é diferente e a biblioteca não pode reconhecê-lo como um arquivo Excel. Eu não consigo entender o porquê.
A única diferença que vejo é que inputStream2 e 3 estão usando o carregador de classe para localizar o arquivo. ( ClassPathResource é uma classe de Primavera).
Eu gostaria de ter o caminho do arquivo separado do sistema. Então, eu preferiria algo como inputStream2 ou 3.
Você tem alguma idéia de por que isso está acontecendo?
Obrigado
Update:
Eu tentei gravar no disco o inputStream e inputStream2.
O arquivo excel que vem com inputStream é Ok. inputStream2 contém um arquivo do Excel com alguns caracteres estranhos que envolvem o conteúdo real.
Parece que corrompe maven o arquivo excel, de alguma forma durante a construção.
Então, é basicamente o arquivo recupero com o carregador de classe (sob /home/xxx/workspace/myproject/target/test-classes/importTest.xls
) que não é ok.
Alguma idéia?
Solução
O problema parece filtragem opção do Maven.
Se os olhares do pom como este
<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>
Quando a opção de filtragem é definido como verdadeiro em xls ele corrompe-los.
Outras dicas
Você já tentou ClassLoader#getResourceAsStream(String)
? Ele provavelmente irá se comportar de forma semelhante à sua segunda tentativa, usando o Class#getResource(String)
, como aludido na documentação deste último.
Meu primeiro pensamento aqui foi que esse arquivo não foi encontrado, mas se ele está constantemente a leitura do mesmo valor (-2300849302551019537
) cada vez que você executar o programa, que sugere que há realmente é um arquivo lá que está sendo lido. Armadilha a declaração depois que iniciar o InputStream
e inspecionar a instância do fluxo no depurador. Você deve ser capaz de encontrar uma referência ao nome do arquivo subjacente. Para tornar isso mais fácil no início, tente usar ClassLoader#getResources(String)
e inspecionar a seqüência de URLs devolvidos.