ObjectInputStream对FileInputStream很满意,对getResourceAsStream不满意

我有一些非常标准的代码,它从流中获取序列化对象,基本上看起来像这样:

   Object getObjectFromStream(InputStream is){ObjectInputStream ois = new ObjectInputStream(is);  return ois.readObject();  } 

然后我在我的资源文件夹中有一个文件,所以在我的开发机器上,我可以将它作为文件引用,或者作为JarResource引用:

   InputStream = new FileInputStream(“/ home /.../ src / main / resources / serializedObjects / testObject”);
   InputStream是= this.getClass()。getResourceAsStream(“/ serializedObjects / testObject”);

在我的脑海中,两者都应该做同样的事情。 然而,当它发生时,两者都解析为有效(非空)流,但FileInputStream正确地从我的getObjectFromStream(InputStream)方法返回一个Object,而getResourceAsStream版本抛出此exception:

   java.io.StreamCorruptedException:无效的流标题:EFBFBDEF
     at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:800)
    在java.io.ObjectInputStream。(ObjectInputStream.java:297)

大多数情况下,我想知道如何解决这个问题,但我也很欣赏理解两个InputStream之间的区别……

EFBFBD是Unicode替换字符U + FFFD的UTF-8表示。 所以,看起来文件是通过一些编码转换过程传递的。

Maven可能是一个嫌疑人,特别是它的资源过滤function。

在你的情况下,Maven正在弄乱你的文件,但是我发现同样的事情有不同的原因,所以我在这里记录它,因为这是谷歌唯一有用的搜索结果。

我将序列化对象保存为unit testing的数据集,并将它们存储在版本控制中。 这是否是一个好主意是辩论,但另一次。

文件以:

 AC ED 00 05 ... 

将它们存储在Git中后,它们变为:

 EF BF BD EF BF BD 00 05 ... 

这会导致错误:

 java.io.StreamCorruptedException: invalid stream header: EFBFBDEF at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:782) at java.io.ObjectInputStream.(ObjectInputStream.java:279) 

Git不仅更改了这些开放字节,还改变了整个文件中的许多字节。 它试图在Windows和Unix风格的行结尾之间进行转换。 用于识别文件是否包含文本的启发式算法失败。

解决方案是添加一个.gitattributes文件,该文件指定了一些要从此处理中排除的文件:

 *.bytes -crlf 

我还确保我的.git/config文件具有以下内容:

 [core] autocrlf = false 

通过这些更改,我删除了索引并强制重置:

 rm .git/index git reset # force rescan of the index git status # any files listed here will experience changes git add -u git commit -m "Line ending normalisation changes." 

希望能帮助别人。 我不是Git的大师,所以可能不需要其中一些步骤,但它们对我有用。

这个对我有用。

   maven-resources-plugin 2.5  UTF-8  xls xlsx jrxml jasper    

一个问题是maven尝试过滤资源文件夹中的所有内容。 创建一个单独的文件夹,然后指示maven不要过滤它。

   ${basedir}/bin false  **/*    

应该没有任何区别 – 您为getResourceAsStream()使用的路径必须找到其他文件。 搜索存储为serializedObjects / testObject的其他文件,看看是否找不到它。 请记住,FileInputStream将相对于当前目录进行查找,而getResourceAsStream()则相对于类路径。