java FileInputStream – 基于如何引用File对象的差异:classloader / filesystem

我正在使用Apache POI从Excel文件中提取一些数据。
我需要一个InputStream来实例化POI HSSFWorkbook类
HSSFWorkbook wb = new HSSFWorkbook(inputStreamX);

如果我尝试构buildInputStream对象,我发现差异

  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(); 

如果我用inputStream构造POI对象,它工作正常。
但是inputStream2和inputStream3抛出这个exception

 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是一个Spring类)。

我想将文件path从系统中分离出来。 所以我更喜欢像inputStream2或3。

你有什么想法,为什么发生这种情况?

谢谢

更新:
我试图写入磁盘的inputStream和inputStream2。
inputStream附带的excel文件是OK的。 inputStream2包含一个包含真实内容的奇怪字符的Excel文件。
maven似乎在构build过程中以某种方式破坏了excel文件。
所以它基本上是我用classLoader(在/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)尝试,正如在后者的文档中提到的那样。

我首先想到的是,没有find这样的文件,但是如果每次运行该程序时始终读取相同的值( -2300849302551019537 ),则表明在那里正在读取的文件是真的。 在初始化您的InputStream之后捕获语句并在debugging器中检查stream实例。 您应该能够find对基础文件名的引用。 为了使这一点更容易,尝试使用ClassLoader#getResources(String)并检查返回的URL的顺序。

Interesting Posts